1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
package command
import (
"fmt"
"strings"
"github.com/ProtonMail/gluon/rfcparser"
)
func TryParseFlagList(p *rfcparser.Parser) ([]string, bool, error) {
if !p.Check(rfcparser.TokenTypeLParen) {
return nil, false, nil
}
flags, err := ParseFlagList(p)
return flags, true, err
}
func ParseFlagList(p *rfcparser.Parser) ([]string, error) {
// flag-list = "(" [flag *(SP flag)] ")"
var flags []string
if err := p.Consume(rfcparser.TokenTypeLParen, "Expected '(' at start of flag list"); err != nil {
return nil, err
}
if !p.Check(rfcparser.TokenTypeRParen) {
{
firstFlag, err := ParseFlag(p)
if err != nil {
return nil, err
}
flags = append(flags, firstFlag)
}
for {
if ok, err := p.Matches(rfcparser.TokenTypeSP); err != nil {
return nil, err
} else if !ok {
break
}
flag, err := ParseFlag(p)
if err != nil {
return nil, err
}
flags = append(flags, flag)
}
}
if err := p.Consume(rfcparser.TokenTypeRParen, "Expected ')' at end of flag list"); err != nil {
return nil, err
}
return flags, nil
}
func ParseFlag(p *rfcparser.Parser) (string, error) {
/*
flag = "\Answered" / "\Flagged" / "\Deleted" /
"\Seen" / "\Draft" / flag-keyword / flag-extension
; Does not include "\Recent"
flag-extension = "\" atom
; Future expansion. Client implementations
; MUST accept flag-extension flags. Server
; implementations MUST NOT generate
; flag-extension flags except as defined by
; future standard or standards-track
; revisions of this specification.
flag-keyword = atom
*/
hasBackslash, err := p.Matches(rfcparser.TokenTypeBackslash)
if err != nil {
return "", err
}
if hasBackslash {
flag, err := p.ParseAtom()
if err != nil {
return "", err
}
if strings.EqualFold(flag, "recent") {
return "", p.MakeError("Recent Flag is not allowed in this context")
}
return fmt.Sprintf("\\%v", flag), nil
}
return p.ParseAtom()
}
|