diff options
author | Robin Jarry <robin@jarry.cc> | 2024-08-14 16:59:11 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2024-08-28 12:06:01 +0200 |
commit | 73dc39c6ee0827fc68b93af8dc438b0e1c14e929 (patch) | |
tree | aff067600ea6326ff179447ed968b6712013b889 /lib/msgstore.go | |
parent | 2950d919a5c5a55bd0eb53d6c41f989d8b70bd55 (diff) | |
download | aerc-73dc39c6ee0827fc68b93af8dc438b0e1c14e929.tar.gz |
treewide: replace uint32 uids with opaque strings
Add a new models.UID type (an alias to string). Replace all occurrences
of uint32 being used as message UID or thread UID with models.UID.
Update all workers to only expose models.UID values and deal with the
conversion internally. Only IMAP needs to convert these to uint32. All
other backends already use plain strings as message identifiers, in
which case no conversion is even needed.
The directory tree implementation needed to be heavily refactored in
order to accommodate thread UID not being usable as a list index.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat (limited to 'lib/msgstore.go')
-rw-r--r-- | lib/msgstore.go | 99 |
1 files changed, 49 insertions, 50 deletions
diff --git a/lib/msgstore.go b/lib/msgstore.go index 5c8b3ef1..1250a9c0 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -20,8 +20,8 @@ import ( type MessageStore struct { sync.Mutex Name string - Deleted map[uint32]interface{} - Messages map[uint32]*models.MessageInfo + Deleted map[models.UID]interface{} + Messages map[models.UID]*models.MessageInfo Sorting bool ui func() *config.UIConfig @@ -30,21 +30,21 @@ type MessageStore struct { ctx context.Context // Ordered list of known UIDs - uids []uint32 + uids []models.UID threads []*types.Thread // Visible UIDs scrollOffset int scrollLen int - selectedUid uint32 - bodyCallbacks map[uint32][]func(*types.FullMessage) + selectedUid models.UID + bodyCallbacks map[models.UID][]func(*types.FullMessage) // marking marker marker.Marker // Search/filter results - results []uint32 + results []models.UID resultIndex int filter *types.SearchCriteria @@ -60,11 +60,11 @@ type MessageStore struct { onUpdate func(store *MessageStore) // TODO: multiple onUpdate handlers onFilterChange func(store *MessageStore) onUpdateDirs func() - pendingBodies map[uint32]interface{} - pendingHeaders map[uint32]interface{} + pendingBodies map[models.UID]interface{} + pendingHeaders map[models.UID]interface{} worker *types.Worker - needsFlags []uint32 + needsFlags []models.UID fetchFlagsDebounce *time.Timer fetchFlagsDelay time.Duration @@ -85,7 +85,7 @@ type MessageStore struct { onSelect func(*models.MessageInfo) } -const MagicUid = 0xFFFFFFFF +const MagicUid = models.UID("") func NewMessageStore(worker *types.Worker, name string, ui func() *config.UIConfig, @@ -97,8 +97,8 @@ func NewMessageStore(worker *types.Worker, name string, ) *MessageStore { return &MessageStore{ Name: name, - Deleted: make(map[uint32]interface{}), - Messages: make(map[uint32]*models.MessageInfo), + Deleted: make(map[models.UID]interface{}), + Messages: make(map[models.UID]*models.MessageInfo), ui: ui, @@ -108,13 +108,12 @@ func NewMessageStore(worker *types.Worker, name string, // default window height until account is drawn once scrollLen: 25, - bodyCallbacks: make(map[uint32][]func(*types.FullMessage)), - - pendingBodies: make(map[uint32]interface{}), - pendingHeaders: make(map[uint32]interface{}), + bodyCallbacks: make(map[models.UID][]func(*types.FullMessage)), + pendingBodies: make(map[models.UID]interface{}), + pendingHeaders: make(map[models.UID]interface{}), worker: worker, - needsFlags: []uint32{}, + needsFlags: []models.UID{}, fetchFlagsDelay: 50 * time.Millisecond, triggerNewEmail: triggerNewEmail, @@ -158,12 +157,12 @@ func (store *MessageStore) UpdateScroll(offset, length int) { store.scrollLen = length } -func (store *MessageStore) FetchHeaders(uids []uint32, +func (store *MessageStore) FetchHeaders(uids []models.UID, cb func(types.WorkerMessage), ) { // 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. - var toFetch []uint32 + var toFetch []models.UID for _, uid := range uids { if _, ok := store.pendingHeaders[uid]; !ok { toFetch = append(toFetch, uid) @@ -189,10 +188,10 @@ func (store *MessageStore) FetchHeaders(uids []uint32, } } -func (store *MessageStore) FetchFull(uids []uint32, cb func(*types.FullMessage)) { +func (store *MessageStore) FetchFull(uids []models.UID, cb func(*types.FullMessage)) { // 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. - var toFetch []uint32 + var toFetch []models.UID for _, uid := range uids { if _, ok := store.pendingBodies[uid]; !ok { toFetch = append(toFetch, uid) @@ -220,7 +219,7 @@ func (store *MessageStore) FetchFull(uids []uint32, cb func(*types.FullMessage)) } } -func (store *MessageStore) FetchBodyPart(uid uint32, part []int, cb func(io.Reader)) { +func (store *MessageStore) FetchBodyPart(uid models.UID, part []int, cb func(io.Reader)) { store.worker.PostAction(&types.FetchMessageBodyPart{ Uid: uid, Part: part, @@ -253,7 +252,7 @@ func merge(to *models.MessageInfo, from *models.MessageInfo) { } func (store *MessageStore) Update(msg types.WorkerMessage) { - var newUids []uint32 + var newUids []models.UID update := false updateThreads := false directoryChange := false @@ -265,7 +264,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { store.Sort(store.sortCriteria, nil) update = true case *types.DirectoryContents: - newMap := make(map[uint32]*models.MessageInfo, len(msg.Uids)) + newMap := make(map[models.UID]*models.MessageInfo, len(msg.Uids)) for i, uid := range msg.Uids { if msg, ok := store.Messages[uid]; ok { newMap[uid] = msg @@ -291,7 +290,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { store.uids = store.builder.Uids() store.threads = msg.Threads - newMap := make(map[uint32]*models.MessageInfo, len(store.uids)) + newMap := make(map[models.UID]*models.MessageInfo, len(store.uids)) for i, uid := range store.uids { if msg, ok := store.Messages[uid]; ok { newMap[uid] = msg @@ -351,13 +350,13 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { break } - toDelete := make(map[uint32]interface{}) + toDelete := make(map[models.UID]interface{}) for _, uid := range msg.Uids { toDelete[uid] = nil delete(store.Messages, uid) delete(store.Deleted, uid) } - uids := make([]uint32, 0, len(store.uids)-len(msg.Uids)) + uids := make([]models.UID, 0, len(store.uids)-len(msg.Uids)) for _, uid := range store.uids { if _, deleted := toDelete[uid]; deleted { continue @@ -369,7 +368,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { store.Select(MagicUid) } - var newResults []uint32 + var newResults []models.UID for _, res := range store.results { if _, deleted := toDelete[res]; !deleted { newResults = append(newResults, res) @@ -528,7 +527,7 @@ func (store *MessageStore) runThreadBuilderNow() { } // Thread returns the thread for the given UId -func (store *MessageStore) Thread(uid uint32) (*types.Thread, error) { +func (store *MessageStore) Thread(uid models.UID) (*types.Thread, error) { if store.builder == nil { return nil, errors.New("no threads found") } @@ -540,15 +539,15 @@ func (store *MessageStore) SelectedThread() (*types.Thread, error) { return store.Thread(store.SelectedUid()) } -func (store *MessageStore) Fold(uid uint32, toggle bool) error { +func (store *MessageStore) Fold(uid models.UID, toggle bool) error { return store.doThreadFolding(uid, true, toggle) } -func (store *MessageStore) Unfold(uid uint32, toggle bool) error { +func (store *MessageStore) Unfold(uid models.UID, toggle bool) error { return store.doThreadFolding(uid, false, toggle) } -func (store *MessageStore) doThreadFolding(uid uint32, hide bool, toggle bool) error { +func (store *MessageStore) doThreadFolding(uid models.UID, hide bool, toggle bool) error { thread, err := store.Thread(uid) if err != nil { return err @@ -596,7 +595,7 @@ func (store *MessageStore) doThreadFolding(uid uint32, hide bool, toggle bool) e return nil } -func (store *MessageStore) Delete(uids []uint32, mfs *types.MultiFileStrategy, +func (store *MessageStore) Delete(uids []models.UID, mfs *types.MultiFileStrategy, cb func(msg types.WorkerMessage), ) { for _, uid := range uids { @@ -618,13 +617,13 @@ func (store *MessageStore) Delete(uids []uint32, mfs *types.MultiFileStrategy, }) } -func (store *MessageStore) revertDeleted(uids []uint32) { +func (store *MessageStore) revertDeleted(uids []models.UID) { for _, uid := range uids { delete(store.Deleted, uid) } } -func (store *MessageStore) Copy(uids []uint32, dest string, createDest bool, +func (store *MessageStore) Copy(uids []models.UID, dest string, createDest bool, mfs *types.MultiFileStrategy, cb func(msg types.WorkerMessage), ) { if createDest { @@ -646,7 +645,7 @@ func (store *MessageStore) Copy(uids []uint32, dest string, createDest bool, }) } -func (store *MessageStore) Move(uids []uint32, dest string, createDest bool, +func (store *MessageStore) Move(uids []models.UID, dest string, createDest bool, mfs *types.MultiFileStrategy, cb func(msg types.WorkerMessage), ) { for _, uid := range uids { @@ -699,7 +698,7 @@ func (store *MessageStore) Append(dest string, flags models.Flags, date time.Tim }) } -func (store *MessageStore) Flag(uids []uint32, flags models.Flags, +func (store *MessageStore) Flag(uids []models.UID, flags models.Flags, enable bool, cb func(msg types.WorkerMessage), ) { store.worker.PostAction(&types.FlagMessages{ @@ -729,7 +728,7 @@ func (store *MessageStore) Flag(uids []uint32, flags models.Flags, }) } -func (store *MessageStore) Answered(uids []uint32, answered bool, +func (store *MessageStore) Answered(uids []models.UID, answered bool, cb func(msg types.WorkerMessage), ) { store.worker.PostAction(&types.AnsweredMessages{ @@ -738,7 +737,7 @@ func (store *MessageStore) Answered(uids []uint32, answered bool, }, cb) } -func (store *MessageStore) Forwarded(uids []uint32, forwarded bool, +func (store *MessageStore) Forwarded(uids []models.UID, forwarded bool, cb func(msg types.WorkerMessage), ) { store.worker.PostAction(&types.ForwardedMessages{ @@ -747,7 +746,7 @@ func (store *MessageStore) Forwarded(uids []uint32, forwarded bool, }, cb) } -func (store *MessageStore) Uids() []uint32 { +func (store *MessageStore) Uids() []models.UID { if store.ThreadedView() && store.builder != nil { if uids := store.builder.Uids(); len(uids) > 0 { return uids @@ -764,7 +763,7 @@ func (store *MessageStore) Selected() *models.MessageInfo { return store.Messages[store.selectedUid] } -func (store *MessageStore) SelectedUid() uint32 { +func (store *MessageStore) SelectedUid() models.UID { if store.selectedUid == MagicUid && len(store.Uids()) > 0 { iter := store.UidsIterator() idx := iter.StartIndex() @@ -776,14 +775,14 @@ func (store *MessageStore) SelectedUid() uint32 { return store.selectedUid } -func (store *MessageStore) Select(uid uint32) { +func (store *MessageStore) Select(uid models.UID) { store.selectPriv(uid, false) if store.onSelect != nil { store.onSelect(store.Selected()) } } -func (store *MessageStore) selectPriv(uid uint32, lockHeld bool) { +func (store *MessageStore) selectPriv(uid models.UID, lockHeld bool) { if !lockHeld { store.threadsMutex.Lock() } @@ -844,14 +843,14 @@ func (store *MessageStore) Prev() { store.NextPrev(-1) } -func (store *MessageStore) Search(terms *types.SearchCriteria, cb func([]uint32)) { +func (store *MessageStore) Search(terms *types.SearchCriteria, cb func([]models.UID)) { store.worker.PostAction(&types.SearchDirectory{ Context: store.ctx, Criteria: terms, }, func(msg types.WorkerMessage) { if msg, ok := msg.(*types.SearchResults); ok { allowedUids := store.Uids() - uids := make([]uint32, 0, len(msg.Uids)) + uids := make([]models.UID, 0, len(msg.Uids)) for _, uid := range msg.Uids { for _, uidCheck := range allowedUids { if uid == uidCheck { @@ -866,14 +865,14 @@ func (store *MessageStore) Search(terms *types.SearchCriteria, cb func([]uint32) }) } -func (store *MessageStore) ApplySearch(results []uint32) { +func (store *MessageStore) ApplySearch(results []models.UID) { store.results = results store.resultIndex = -1 store.NextResult() } // IsResult returns true if uid is a search result -func (store *MessageStore) IsResult(uid uint32) bool { +func (store *MessageStore) IsResult(uid models.UID) bool { for _, hit := range store.results { if hit == uid { return true @@ -935,7 +934,7 @@ func (store *MessageStore) PrevResult() { store.nextPrevResult(-1) } -func (store *MessageStore) ModifyLabels(uids []uint32, add, remove []string, +func (store *MessageStore) ModifyLabels(uids []models.UID, add, remove []string, cb func(msg types.WorkerMessage), ) { store.worker.PostAction(&types.ModifyLabels{ @@ -999,7 +998,7 @@ func (store *MessageStore) Marker() marker.Marker { } // FindIndexByUid returns the index in store.Uids() or -1 if not found -func (store *MessageStore) FindIndexByUid(uid uint32) int { +func (store *MessageStore) FindIndexByUid(uid models.UID) int { for idx, u := range store.Uids() { if u == uid { return idx @@ -1029,7 +1028,7 @@ func (store *MessageStore) fetchFlags() { Context: store.ctx, Uids: store.needsFlags, }, nil) - store.needsFlags = []uint32{} + store.needsFlags = []models.UID{} store.Unlock() }) } |