package parser import ( "strings" "asciigoat.org/core/lexer" ) type commaArrayParser struct { TextParser out []string } func (p *commaArrayParser) lexStart() (lexer.StateFn, error) { for { r, _, err := p.ReadRune() switch { case err != nil: // EOF return nil, err case r == RuneQuotes: // Quoted Value return p.lexQuotedString, nil case IsNewLine(r): // new lines are acceptable when parsing a string for // comma delimited arrays. but make sure we discard it // complete p.UnreadRune() p.AcceptNewLine() p.Discard() case lexer.IsSpace(r): // discard whitespace outside quotes p.Discard() default: p.UnreadRune() return p.lexWord, nil } } } func (p *commaArrayParser) lexWord() (lexer.StateFn, error) { for { r, _, err := p.ReadRune() switch { case err != nil: // done. store what we got and move on _, s := p.Emit() p.out = append(p.out, s) return nil, err case r == ',': // done _, s := p.Emit() // remove comma, trim and append to output s = strings.TrimRightFunc(s[:len(s)-1], IsSpace) p.out = append(p.out, s) return p.lexStart, nil } } } func (p *commaArrayParser) lexQuotedString() (lexer.StateFn, error) { s, err := lexQuotedString(&p.TextParser) if err != nil { return nil, err } p.Discard() p.out = append(p.out, s) return p.lexStart, nil } func (p *commaArrayParser) Run() ([]string, error) { err := lexer.Run(p.lexStart) return p.out, err } // SplitCommaArray splits comma separated strings, removing whitespace // and respecting quoted literals. func SplitCommaArray(s string) ([]string, error) { if s != "" { var p commaArrayParser p.InitString(s) return p.Run() } return nil, nil }