krampus19/gut/lineparser.go
2020-01-15 19:03:52 +01:00

67 lines
1.2 KiB
Go

package gut
import (
"errors"
"io"
"io/ioutil"
"strings"
)
type LineParser struct {
lines []string
i int
err error
}
var ErrUnexpectedEnd = errors.New("unexpected end of file")
func (p *LineParser) EOF() bool { return p.i == len(p.lines) }
func (p *LineParser) EmitErr(err error) ParseLineFn {
p.err = err
return nil
}
func (p *LineParser) Next() string {
i := p.i
p.i++
return p.lines[i]
}
func (p *LineParser) Peek() string { return p.lines[p.i] }
func (p *LineParser) SkipSpaceEOF() bool {
for !p.EOF() && len(strings.TrimSpace(p.Peek())) == 0 {
p.Next()
}
return p.EOF()
}
func SkipSpaceBeforeContent(next ParseLineFn) ParseLineFn {
return func(p *LineParser) ParseLineFn {
if p.SkipSpaceEOF() {
return p.EmitErr(ErrUnexpectedEnd)
}
return next
}
}
type ParseLineFn func(p *LineParser) ParseLineFn
func ParseLines(r io.Reader, fn ParseLineFn) error {
content, err := ioutil.ReadAll(r)
if err != nil {
return err
}
lines := strings.Split(string(content), "\n")
for i, line := range lines {
lines[i] = strings.TrimRight(line, "\r\n")
}
parser := &LineParser{lines: lines}
for fn != nil {
fn = fn(parser)
}
return parser.err
}