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 /worker/mbox | |
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 'worker/mbox')
-rw-r--r-- | worker/mbox/io.go | 7 | ||||
-rw-r--r-- | worker/mbox/models.go | 42 | ||||
-rw-r--r-- | worker/mbox/worker.go | 6 |
3 files changed, 26 insertions, 29 deletions
diff --git a/worker/mbox/io.go b/worker/mbox/io.go index f5fbc596..22d0d023 100644 --- a/worker/mbox/io.go +++ b/worker/mbox/io.go @@ -12,7 +12,6 @@ import ( func Read(r io.Reader) ([]rfc822.RawMessage, error) { mbr := mbox.NewReader(r) - uid := uint32(0) messages := make([]rfc822.RawMessage, 0) for { msg, err := mbr.NextMessage() @@ -28,10 +27,10 @@ func Read(r io.Reader) ([]rfc822.RawMessage, error) { } messages = append(messages, &message{ - uid: uid, flags: models.SeenFlag, content: content, + uid: uidFromContents(content), + flags: models.SeenFlag, + content: content, }) - - uid++ } return messages, nil } diff --git a/worker/mbox/models.go b/worker/mbox/models.go index 5acd6f5a..ebfe5d32 100644 --- a/worker/mbox/models.go +++ b/worker/mbox/models.go @@ -2,6 +2,8 @@ package mboxer import ( "bytes" + "crypto/sha256" + "encoding/hex" "fmt" "io" @@ -49,7 +51,7 @@ func (md *mailboxContainer) DirectoryInfo(file string) *models.DirectoryInfo { } } -func (md *mailboxContainer) Copy(dest, src string, uids []uint32) error { +func (md *mailboxContainer) Copy(dest, src string, uids []models.UID) error { srcmbox, ok := md.Mailbox(src) if !ok { return fmt.Errorf("source %s not found", src) @@ -69,15 +71,15 @@ func (md *mailboxContainer) Copy(dest, src string, uids []uint32) error { if found { msg, err := srcmbox.Message(uidSrc) if err != nil { - return fmt.Errorf("could not get message with uid %d from folder %s", uidSrc, src) + return fmt.Errorf("could not get message with uid %s from folder %s", uidSrc, src) } r, err := msg.NewReader() if err != nil { - return fmt.Errorf("could not get reader for message with uid %d", uidSrc) + return fmt.Errorf("could not get reader for message with uid %s", uidSrc) } flags, err := msg.ModelFlags() if err != nil { - return fmt.Errorf("could not get flags for message with uid %d", uidSrc) + return fmt.Errorf("could not get flags for message with uid %s", uidSrc) } err = destmbox.Append(r, flags) if err != nil { @@ -94,24 +96,24 @@ type container struct { messages []rfc822.RawMessage } -func (f *container) Uids() []uint32 { - uids := make([]uint32, len(f.messages)) +func (f *container) Uids() []models.UID { + uids := make([]models.UID, len(f.messages)) for i, m := range f.messages { uids[i] = m.UID() } return uids } -func (f *container) Message(uid uint32) (rfc822.RawMessage, error) { +func (f *container) Message(uid models.UID) (rfc822.RawMessage, error) { for _, m := range f.messages { if uid == m.UID() { return m, nil } } - return &message{}, fmt.Errorf("uid [%d] not found", uid) + return &message{}, fmt.Errorf("uid [%s] not found", uid) } -func (f *container) Delete(uids []uint32) (deleted []uint32) { +func (f *container) Delete(uids []models.UID) (deleted []models.UID) { newMessages := make([]rfc822.RawMessage, 0) for _, m := range f.messages { del := false @@ -131,32 +133,28 @@ func (f *container) Delete(uids []uint32) (deleted []uint32) { return } -func (f *container) newUid() (next uint32) { - for _, m := range f.messages { - if uid := m.UID(); uid > next { - next = uid - } - } - next++ - return -} - func (f *container) Append(r io.Reader, flags models.Flags) error { data, err := io.ReadAll(r) if err != nil { return err } f.messages = append(f.messages, &message{ - uid: f.newUid(), + uid: uidFromContents(data), flags: flags, content: data, }) return nil } +func uidFromContents(data []byte) models.UID { + sum := sha256.New() + sum.Write(data) + return models.UID(hex.EncodeToString(sum.Sum(nil))) +} + // message implements the lib.RawMessage interface type message struct { - uid uint32 + uid models.UID flags models.Flags content []byte } @@ -173,7 +171,7 @@ func (m *message) Labels() ([]string, error) { return nil, nil } -func (m *message) UID() uint32 { +func (m *message) UID() models.UID { return m.uid } diff --git a/worker/mbox/worker.go b/worker/mbox/worker.go index 1f4a4965..72a44368 100644 --- a/worker/mbox/worker.go +++ b/worker/mbox/worker.go @@ -405,7 +405,7 @@ func (w *mboxWorker) PathSeparator() string { return "/" } -func filterUids(folder *container, uids []uint32, criteria *types.SearchCriteria) ([]uint32, error) { +func filterUids(folder *container, uids []models.UID, criteria *types.SearchCriteria) ([]models.UID, error) { log.Debugf("Search with parsed criteria: %#v", criteria) m := make([]rfc822.RawMessage, 0, len(uids)) for _, uid := range uids { @@ -419,9 +419,9 @@ func filterUids(folder *container, uids []uint32, criteria *types.SearchCriteria return lib.Search(m, criteria) } -func sortUids(folder *container, uids []uint32, +func sortUids(folder *container, uids []models.UID, criteria []*types.SortCriterion, -) ([]uint32, error) { +) ([]models.UID, error) { var infos []*models.MessageInfo needSize := false for _, item := range criteria { |