package imaputils import ( "git.sr.ht/~blallo/papero/config" "github.com/emersion/go-imap" ) type ListMessagesOpts struct { Mailbox string Limit uint32 } func ListMessages(conf *config.AccountData, opts *ListMessagesOpts, debug bool) ([]*imap.Message, error) { var empty []*imap.Message conn := NewConnection(conf) err := conn.Start(debug) if err != nil { return empty, err } defer conn.Close() return ListMessagesInSession(conn, opts) } func ListMessagesInSession(conn *IMAPConnection, opts *ListMessagesOpts) ([]*imap.Message, error) { var messages []*imap.Message mbox, err := conn.client.Select(opts.Mailbox, true) if err != nil { return messages, err } return getMessages(mbox, conn, opts.Limit) } func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit uint32) ([]*imap.Message, error) { var start uint32 var msgs []*imap.Message seqset := new(imap.SeqSet) messages := make(chan *imap.Message, 10) done := make(chan error, 1) switch { case limit == 0: start = 1 case mbox.Messages > limit: start = mbox.Messages - limit + 1 default: start = 1 } seqset.AddRange(start, mbox.Messages) go func() { done <- conn.client.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags}, messages) }() for msg := range messages { msgs = append(msgs, msg) } if err := <-done; err != nil { return []*imap.Message{}, err } return msgs, nil }