package jmap import ( "strings" "git.sr.ht/~rjarry/aerc/worker/types" "git.sr.ht/~rockorager/go-jmap" "git.sr.ht/~rockorager/go-jmap/mail/email" "git.sr.ht/~rockorager/go-jmap/mail/mailbox" ) func (w *JMAPWorker) translateSearch( mbox jmap.ID, criteria *types.SearchCriteria, ) email.Filter { cond := new(email.FilterCondition) if mbox == "" { // all mail virtual folder: display all but trash and spam var mboxes []jmap.ID if id, ok := w.roles[mailbox.RoleJunk]; ok { mboxes = append(mboxes, id) } if id, ok := w.roles[mailbox.RoleTrash]; ok { mboxes = append(mboxes, id) } cond.InMailboxOtherThan = mboxes } else { cond.InMailbox = mbox } if criteria == nil { return cond } // dates if !criteria.StartDate.IsZero() { cond.After = &criteria.StartDate } if !criteria.EndDate.IsZero() { cond.Before = &criteria.EndDate } // general search terms terms := strings.Join(criteria.Terms, " ") switch { case criteria.SearchAll: cond.Text = terms case criteria.SearchBody: cond.Body = terms default: cond.Subject = terms } filter := &email.FilterOperator{Operator: jmap.OperatorAND} filter.Conditions = append(filter.Conditions, cond) // keywords/flags for kw := range flagsToKeywords(criteria.WithFlags) { filter.Conditions = append(filter.Conditions, &email.FilterCondition{HasKeyword: kw}) } for kw := range flagsToKeywords(criteria.WithoutFlags) { filter.Conditions = append(filter.Conditions, &email.FilterCondition{NotKeyword: kw}) } // recipients addrs := &email.FilterOperator{ Operator: jmap.OperatorOR, } for _, from := range criteria.From { addrs.Conditions = append(addrs.Conditions, &email.FilterCondition{From: from}) } for _, to := range criteria.To { addrs.Conditions = append(addrs.Conditions, &email.FilterCondition{To: to}) } for _, cc := range criteria.Cc { addrs.Conditions = append(addrs.Conditions, &email.FilterCondition{Cc: cc}) } if len(addrs.Conditions) > 0 { filter.Conditions = append(filter.Conditions, addrs) } // specific headers headers := &email.FilterOperator{ Operator: jmap.OperatorAND, } for h, values := range criteria.Headers { for _, v := range values { headers.Conditions = append(headers.Conditions, &email.FilterCondition{Header: []string{h, v}}) } } if len(headers.Conditions) > 0 { filter.Conditions = append(filter.Conditions, headers) } return filter }