Summary
The internal/client/email.go file contains several nearly identical methods for updating email properties via JMAP patches:
MarkAsRead() — sets keywords/$seen to true
SetFlagged() — sets keywords/$flagged to true
SetUnflagged() — sets keywords/$flagged to nil
MarkAsSpam() — moves to junk mailbox
MoveEmails() — moves to a target mailbox
The first three in particular share the same structure: batch loop, patch construction, request/response handling, and error collection. They differ only in the patch value applied.
Proposal
Extract a shared helper, something like:
func (c *Client) patchEmails(emailIDs []string, patchFn func(id string) jmap.Patch) (succeeded []string, errors []string)
Each caller would then reduce to a one-liner supplying its patch. MarkAsSpam and MoveEmails may also benefit if their mailbox-lookup logic can be separated from the patch-and-send loop.
Context
This duplication was introduced incrementally as new commands were added (mark-read, then flag/unflag in #15). Each method is ~55 lines and they share ~90% of their code.
Summary
The
internal/client/email.gofile contains several nearly identical methods for updating email properties via JMAP patches:MarkAsRead()— setskeywords/$seentotrueSetFlagged()— setskeywords/$flaggedtotrueSetUnflagged()— setskeywords/$flaggedtonilMarkAsSpam()— moves to junk mailboxMoveEmails()— moves to a target mailboxThe first three in particular share the same structure: batch loop, patch construction, request/response handling, and error collection. They differ only in the patch value applied.
Proposal
Extract a shared helper, something like:
Each caller would then reduce to a one-liner supplying its patch.
MarkAsSpamandMoveEmailsmay also benefit if their mailbox-lookup logic can be separated from the patch-and-send loop.Context
This duplication was introduced incrementally as new commands were added (
mark-read, thenflag/unflagin #15). Each method is ~55 lines and they share ~90% of their code.