64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package commands
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/emersion/go-imap"
|
|
)
|
|
|
|
// Fetch is a FETCH command, as defined in RFC 3501 section 6.4.5.
|
|
type Fetch struct {
|
|
SeqSet *imap.SeqSet
|
|
Items []imap.FetchItem
|
|
}
|
|
|
|
func (cmd *Fetch) Command() *imap.Command {
|
|
// Handle FETCH macros separately as they should not be serialized within parentheses
|
|
if len(cmd.Items) == 1 && (cmd.Items[0] == imap.FetchAll || cmd.Items[0] == imap.FetchFast || cmd.Items[0] == imap.FetchFull) {
|
|
return &imap.Command{
|
|
Name: "FETCH",
|
|
Arguments: []interface{}{cmd.SeqSet, imap.RawString(cmd.Items[0])},
|
|
}
|
|
} else {
|
|
items := make([]interface{}, len(cmd.Items))
|
|
for i, item := range cmd.Items {
|
|
items[i] = imap.RawString(item)
|
|
}
|
|
|
|
return &imap.Command{
|
|
Name: "FETCH",
|
|
Arguments: []interface{}{cmd.SeqSet, items},
|
|
}
|
|
}
|
|
}
|
|
|
|
func (cmd *Fetch) Parse(fields []interface{}) error {
|
|
if len(fields) < 2 {
|
|
return errors.New("No enough arguments")
|
|
}
|
|
|
|
var err error
|
|
if seqset, ok := fields[0].(string); !ok {
|
|
return errors.New("Sequence set must be an atom")
|
|
} else if cmd.SeqSet, err = imap.ParseSeqSet(seqset); err != nil {
|
|
return err
|
|
}
|
|
|
|
switch items := fields[1].(type) {
|
|
case string: // A macro or a single item
|
|
cmd.Items = imap.FetchItem(strings.ToUpper(items)).Expand()
|
|
case []interface{}: // A list of items
|
|
cmd.Items = make([]imap.FetchItem, 0, len(items))
|
|
for _, v := range items {
|
|
itemStr, _ := v.(string)
|
|
item := imap.FetchItem(strings.ToUpper(itemStr))
|
|
cmd.Items = append(cmd.Items, item.Expand()...)
|
|
}
|
|
default:
|
|
return errors.New("Items must be either a string or a list")
|
|
}
|
|
|
|
return nil
|
|
}
|