1// Package imap implements IMAP4rev1 (RFC 3501).
2package imap
3
4import (
5	"errors"
6	"io"
7	"strings"
8)
9
10// A StatusItem is a mailbox status data item that can be retrieved with a
11// STATUS command. See RFC 3501 section 6.3.10.
12type StatusItem string
13
14const (
15	StatusMessages    StatusItem = "MESSAGES"
16	StatusRecent      StatusItem = "RECENT"
17	StatusUidNext     StatusItem = "UIDNEXT"
18	StatusUidValidity StatusItem = "UIDVALIDITY"
19	StatusUnseen      StatusItem = "UNSEEN"
20)
21
22// A FetchItem is a message data item that can be fetched.
23type FetchItem string
24
25// List of items that can be fetched.
26const (
27	// Macros
28	FetchAll  FetchItem = "ALL"
29	FetchFast FetchItem = "FAST"
30	FetchFull FetchItem = "FULL"
31
32	// Items
33	FetchBody          FetchItem = "BODY"
34	FetchBodyStructure FetchItem = "BODYSTRUCTURE"
35	FetchEnvelope      FetchItem = "ENVELOPE"
36	FetchFlags         FetchItem = "FLAGS"
37	FetchInternalDate  FetchItem = "INTERNALDATE"
38	FetchRFC822        FetchItem = "RFC822"
39	FetchRFC822Header  FetchItem = "RFC822.HEADER"
40	FetchRFC822Size    FetchItem = "RFC822.SIZE"
41	FetchRFC822Text    FetchItem = "RFC822.TEXT"
42	FetchUid           FetchItem = "UID"
43)
44
45// Expand expands the item if it's a macro.
46func (item FetchItem) Expand() []FetchItem {
47	switch item {
48	case FetchAll:
49		return []FetchItem{FetchFlags, FetchInternalDate, FetchRFC822Size, FetchEnvelope}
50	case FetchFast:
51		return []FetchItem{FetchFlags, FetchInternalDate, FetchRFC822Size}
52	case FetchFull:
53		return []FetchItem{FetchFlags, FetchInternalDate, FetchRFC822Size, FetchEnvelope, FetchBody}
54	default:
55		return []FetchItem{item}
56	}
57}
58
59// FlagsOp is an operation that will be applied on message flags.
60type FlagsOp string
61
62const (
63	// SetFlags replaces existing flags by new ones.
64	SetFlags FlagsOp = "FLAGS"
65	// AddFlags adds new flags.
66	AddFlags = "+FLAGS"
67	// RemoveFlags removes existing flags.
68	RemoveFlags = "-FLAGS"
69)
70
71// silentOp can be appended to a FlagsOp to prevent the operation from
72// triggering unilateral message updates.
73const silentOp = ".SILENT"
74
75// A StoreItem is a message data item that can be updated.
76type StoreItem string
77
78// FormatFlagsOp returns the StoreItem that executes the flags operation op.
79func FormatFlagsOp(op FlagsOp, silent bool) StoreItem {
80	s := string(op)
81	if silent {
82		s += silentOp
83	}
84	return StoreItem(s)
85}
86
87// ParseFlagsOp parses a flags operation from StoreItem.
88func ParseFlagsOp(item StoreItem) (op FlagsOp, silent bool, err error) {
89	itemStr := string(item)
90	silent = strings.HasSuffix(itemStr, silentOp)
91	if silent {
92		itemStr = strings.TrimSuffix(itemStr, silentOp)
93	}
94	op = FlagsOp(itemStr)
95
96	if op != SetFlags && op != AddFlags && op != RemoveFlags {
97		err = errors.New("Unsupported STORE operation")
98	}
99	return
100}
101
102// CharsetReader, if non-nil, defines a function to generate charset-conversion
103// readers, converting from the provided charset into UTF-8. Charsets are always
104// lower-case. utf-8 and us-ascii charsets are handled by default. One of the
105// the CharsetReader's result values must be non-nil.
106var CharsetReader func(charset string, r io.Reader) (io.Reader, error)
107