mirror of
https://github.com/emersion/go-imap
synced 2026-07-01 19:14:34 +00:00
All commands embed a base struct previously called "cmd". The
"cmd" type exports a Wait method, intended to be used for simple
commands which don't return any additional data. Typical usage:
type MyCommand {
cmd
}
Unfortunately, even if "cmd" is an unexported field, its Wait method
is accessible to other packages. This causes issues for commands
which need to read a bunch of untagged responses before completing.
Fix this by rejiggering the command types. Introduce a baseCommand
type which is embedded in all command types and doesn't export any
method. Add a Command type which exposes a single Wait method for
simple commands.
Closes: https://github.com/emersion/go-imap/issues/641
38 lines
1.0 KiB
Go
38 lines
1.0 KiB
Go
package imapclient
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/emersion/go-imap/v2"
|
|
"github.com/emersion/go-imap/v2/internal/imapwire"
|
|
)
|
|
|
|
// Copy sends a COPY command.
|
|
func (c *Client) Copy(numSet imap.NumSet, mailbox string) *CopyCommand {
|
|
cmd := &CopyCommand{}
|
|
enc := c.beginCommand(uidCmdName("COPY", imapwire.NumSetKind(numSet)), cmd)
|
|
enc.SP().NumSet(numSet).SP().Mailbox(mailbox)
|
|
enc.end()
|
|
return cmd
|
|
}
|
|
|
|
// CopyCommand is a COPY command.
|
|
type CopyCommand struct {
|
|
commandBase
|
|
data imap.CopyData
|
|
}
|
|
|
|
func (cmd *CopyCommand) Wait() (*imap.CopyData, error) {
|
|
return &cmd.data, cmd.wait()
|
|
}
|
|
|
|
func readRespCodeCopyUID(dec *imapwire.Decoder) (uidValidity uint32, srcUIDs, dstUIDs imap.UIDSet, err error) {
|
|
if !dec.ExpectNumber(&uidValidity) || !dec.ExpectSP() || !dec.ExpectUIDSet(&srcUIDs) || !dec.ExpectSP() || !dec.ExpectUIDSet(&dstUIDs) {
|
|
return 0, nil, nil, dec.Err()
|
|
}
|
|
if srcUIDs.Dynamic() || dstUIDs.Dynamic() {
|
|
return 0, nil, nil, fmt.Errorf("imapclient: server returned dynamic number set in COPYUID response")
|
|
}
|
|
return uidValidity, srcUIDs, dstUIDs, nil
|
|
}
|