Use []uint32 instead of imap.SeqSet

A sequence-set is an IMAP-specific implementation detail. Throughout the
UI, aerc simply operates using lists of opaque identifiers. In order to
loosen the coupling between the UI and IMAP in particular, replace most
usages of imap.SeqSet with []uint32, leaving the translation to a SeqSet
to the IMAP backend as needed.
This commit is contained in:
Ben Burwell 2019-07-07 22:43:57 -04:00 committed by Drew DeVault
parent cce7cb4808
commit 88c379dcba
6 changed files with 41 additions and 41 deletions

View file

@ -55,10 +55,10 @@ func (store *MessageStore) FetchHeaders(uids []uint32,
// TODO: this could be optimized by pre-allocating toFetch and trimming it // TODO: this could be optimized by pre-allocating toFetch and trimming it
// at the end. In practice we expect to get most messages back in one frame. // at the end. In practice we expect to get most messages back in one frame.
var toFetch imap.SeqSet var toFetch []uint32
for _, uid := range uids { for _, uid := range uids {
if _, ok := store.pendingHeaders[uid]; !ok { if _, ok := store.pendingHeaders[uid]; !ok {
toFetch.AddNum(uint32(uid)) toFetch = append(toFetch, uid)
store.pendingHeaders[uid] = nil store.pendingHeaders[uid] = nil
if cb != nil { if cb != nil {
if list, ok := store.headerCallbacks[uid]; ok { if list, ok := store.headerCallbacks[uid]; ok {
@ -69,7 +69,7 @@ func (store *MessageStore) FetchHeaders(uids []uint32,
} }
} }
} }
if !toFetch.Empty() { if len(toFetch) > 0 {
store.worker.PostAction(&types.FetchMessageHeaders{Uids: toFetch}, nil) store.worker.PostAction(&types.FetchMessageHeaders{Uids: toFetch}, nil)
} }
} }
@ -77,10 +77,10 @@ func (store *MessageStore) FetchHeaders(uids []uint32,
func (store *MessageStore) FetchFull(uids []uint32, cb func(io.Reader)) { func (store *MessageStore) FetchFull(uids []uint32, cb func(io.Reader)) {
// TODO: this could be optimized by pre-allocating toFetch and trimming it // TODO: this could be optimized by pre-allocating toFetch and trimming it
// at the end. In practice we expect to get most messages back in one frame. // at the end. In practice we expect to get most messages back in one frame.
var toFetch imap.SeqSet var toFetch []uint32
for _, uid := range uids { for _, uid := range uids {
if _, ok := store.pendingBodies[uid]; !ok { if _, ok := store.pendingBodies[uid]; !ok {
toFetch.AddNum(uint32(uid)) toFetch = append(toFetch, uid)
store.pendingBodies[uid] = nil store.pendingBodies[uid] = nil
if cb != nil { if cb != nil {
if list, ok := store.bodyCallbacks[uid]; ok { if list, ok := store.bodyCallbacks[uid]; ok {
@ -91,7 +91,7 @@ func (store *MessageStore) FetchFull(uids []uint32, cb func(io.Reader)) {
} }
} }
} }
if !toFetch.Empty() { if len(toFetch) > 0 {
store.worker.PostAction(&types.FetchFullMessages{Uids: toFetch}, nil) store.worker.PostAction(&types.FetchFullMessages{Uids: toFetch}, nil)
} }
} }
@ -210,24 +210,17 @@ func (store *MessageStore) update() {
func (store *MessageStore) Delete(uids []uint32, func (store *MessageStore) Delete(uids []uint32,
cb func(msg types.WorkerMessage)) { cb func(msg types.WorkerMessage)) {
var set imap.SeqSet
for _, uid := range uids { for _, uid := range uids {
set.AddNum(uid)
store.Deleted[uid] = nil store.Deleted[uid] = nil
} }
store.worker.PostAction(&types.DeleteMessages{Uids: set}, cb) store.worker.PostAction(&types.DeleteMessages{Uids: uids}, cb)
store.update() store.update()
} }
func (store *MessageStore) Copy(uids []uint32, dest string, createDest bool, func (store *MessageStore) Copy(uids []uint32, dest string, createDest bool,
cb func(msg types.WorkerMessage)) { cb func(msg types.WorkerMessage)) {
var set imap.SeqSet
for _, uid := range uids {
set.AddNum(uid)
}
if createDest { if createDest {
store.worker.PostAction(&types.CreateDirectory{ store.worker.PostAction(&types.CreateDirectory{
Directory: dest, Directory: dest,
@ -236,16 +229,14 @@ func (store *MessageStore) Copy(uids []uint32, dest string, createDest bool,
store.worker.PostAction(&types.CopyMessages{ store.worker.PostAction(&types.CopyMessages{
Destination: dest, Destination: dest,
Uids: set, Uids: uids,
}, cb) }, cb)
} }
func (store *MessageStore) Move(uids []uint32, dest string, createDest bool, func (store *MessageStore) Move(uids []uint32, dest string, createDest bool,
cb func(msg types.WorkerMessage)) { cb func(msg types.WorkerMessage)) {
var set imap.SeqSet
for _, uid := range uids { for _, uid := range uids {
set.AddNum(uid)
store.Deleted[uid] = nil store.Deleted[uid] = nil
} }
@ -257,13 +248,13 @@ func (store *MessageStore) Move(uids []uint32, dest string, createDest bool,
store.worker.PostAction(&types.CopyMessages{ store.worker.PostAction(&types.CopyMessages{
Destination: dest, Destination: dest,
Uids: set, Uids: uids,
}, func(msg types.WorkerMessage) { }, func(msg types.WorkerMessage) {
switch msg.(type) { switch msg.(type) {
case *types.Error: case *types.Error:
cb(msg) cb(msg)
case *types.Done: case *types.Done:
store.worker.PostAction(&types.DeleteMessages{Uids: set}, cb) store.worker.PostAction(&types.DeleteMessages{Uids: uids}, cb)
} }
}) })
@ -273,14 +264,9 @@ func (store *MessageStore) Move(uids []uint32, dest string, createDest bool,
func (store *MessageStore) Read(uids []uint32, read bool, func (store *MessageStore) Read(uids []uint32, read bool,
cb func(msg types.WorkerMessage)) { cb func(msg types.WorkerMessage)) {
var set imap.SeqSet
for _, uid := range uids {
set.AddNum(uid)
}
store.worker.PostAction(&types.ReadMessages{ store.worker.PostAction(&types.ReadMessages{
Read: read, Read: read,
Uids: set, Uids: uids,
}, cb) }, cb)
} }

View file

@ -31,8 +31,7 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders(
imap.FetchUid, imap.FetchUid,
section.FetchItem(), section.FetchItem(),
} }
imapw.handleFetchMessages(msg, msg.Uids, items, section)
imapw.handleFetchMessages(msg, &msg.Uids, items, section)
} }
func (imapw *IMAPWorker) handleFetchMessageBodyPart( func (imapw *IMAPWorker) handleFetchMessageBodyPart(
@ -46,9 +45,7 @@ func (imapw *IMAPWorker) handleFetchMessageBodyPart(
imap.FetchUid, imap.FetchUid,
section.FetchItem(), section.FetchItem(),
} }
uids := imap.SeqSet{} imapw.handleFetchMessages(msg, []uint32{msg.Uid}, items, section)
uids.AddNum(msg.Uid)
imapw.handleFetchMessages(msg, &uids, items, section)
} }
func (imapw *IMAPWorker) handleFetchFullMessages( func (imapw *IMAPWorker) handleFetchFullMessages(
@ -61,11 +58,11 @@ func (imapw *IMAPWorker) handleFetchFullMessages(
imap.FetchUid, imap.FetchUid,
section.FetchItem(), section.FetchItem(),
} }
imapw.handleFetchMessages(msg, &msg.Uids, items, section) imapw.handleFetchMessages(msg, msg.Uids, items, section)
} }
func (imapw *IMAPWorker) handleFetchMessages( func (imapw *IMAPWorker) handleFetchMessages(
msg types.WorkerMessage, uids *imap.SeqSet, items []imap.FetchItem, msg types.WorkerMessage, uids []uint32, items []imap.FetchItem,
section *imap.BodySectionName) { section *imap.BodySectionName) {
messages := make(chan *imap.Message) messages := make(chan *imap.Message)
@ -132,7 +129,8 @@ func (imapw *IMAPWorker) handleFetchMessages(
done <- nil done <- nil
}() }()
if err := imapw.client.UidFetch(uids, items, messages); err != nil { set := toSeqSet(uids)
if err := imapw.client.UidFetch(set, items, messages); err != nil {
imapw.worker.PostMessage(&types.Error{ imapw.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,

View file

@ -9,7 +9,8 @@ import (
func (imapw *IMAPWorker) handleDeleteMessages(msg *types.DeleteMessages) { func (imapw *IMAPWorker) handleDeleteMessages(msg *types.DeleteMessages) {
item := imap.FormatFlagsOp(imap.AddFlags, true) item := imap.FormatFlagsOp(imap.AddFlags, true)
flags := []interface{}{imap.DeletedFlag} flags := []interface{}{imap.DeletedFlag}
if err := imapw.client.UidStore(&msg.Uids, item, flags, nil); err != nil { uids := toSeqSet(msg.Uids)
if err := imapw.client.UidStore(uids, item, flags, nil); err != nil {
imapw.worker.PostMessage(&types.Error{ imapw.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,
@ -49,7 +50,8 @@ func (imapw *IMAPWorker) handleReadMessages(msg *types.ReadMessages) {
item = imap.FormatFlagsOp(imap.RemoveFlags, true) item = imap.FormatFlagsOp(imap.RemoveFlags, true)
flags = []interface{}{imap.SeenFlag} flags = []interface{}{imap.SeenFlag}
} }
if err := imapw.client.UidStore(&msg.Uids, item, flags, nil); err != nil { uids := toSeqSet(msg.Uids)
if err := imapw.client.UidStore(uids, item, flags, nil); err != nil {
imapw.worker.PostMessage(&types.Error{ imapw.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,

13
worker/imap/imap.go Normal file
View file

@ -0,0 +1,13 @@
package imap
import (
"github.com/emersion/go-imap"
)
func toSeqSet(uids []uint32) *imap.SeqSet {
var set imap.SeqSet
for _, uid := range uids {
set.AddNum(uid)
}
return &set
}

View file

@ -7,7 +7,8 @@ import (
) )
func (imapw *IMAPWorker) handleCopyMessages(msg *types.CopyMessages) { func (imapw *IMAPWorker) handleCopyMessages(msg *types.CopyMessages) {
if err := imapw.client.UidCopy(&msg.Uids, msg.Destination); err != nil { uids := toSeqSet(msg.Uids)
if err := imapw.client.UidCopy(uids, msg.Destination); err != nil {
imapw.worker.PostMessage(&types.Error{ imapw.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,

View file

@ -94,12 +94,12 @@ type CreateDirectory struct {
type FetchMessageHeaders struct { type FetchMessageHeaders struct {
Message Message
Uids imap.SeqSet Uids []uint32
} }
type FetchFullMessages struct { type FetchFullMessages struct {
Message Message
Uids imap.SeqSet Uids []uint32
} }
type FetchMessageBodyPart struct { type FetchMessageBodyPart struct {
@ -110,20 +110,20 @@ type FetchMessageBodyPart struct {
type DeleteMessages struct { type DeleteMessages struct {
Message Message
Uids imap.SeqSet Uids []uint32
} }
// Marks messages as read or unread // Marks messages as read or unread
type ReadMessages struct { type ReadMessages struct {
Message Message
Read bool Read bool
Uids imap.SeqSet Uids []uint32
} }
type CopyMessages struct { type CopyMessages struct {
Message Message
Destination string Destination string
Uids imap.SeqSet Uids []uint32
} }
type AppendMessage struct { type AppendMessage struct {