about summary refs log tree commit diff
path: root/vendor/github.com/ncruces/go-strftime/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ncruces/go-strftime/parser.go')
-rw-r--r--vendor/github.com/ncruces/go-strftime/parser.go107
1 files changed, 107 insertions, 0 deletions
diff --git a/vendor/github.com/ncruces/go-strftime/parser.go b/vendor/github.com/ncruces/go-strftime/parser.go
new file mode 100644
index 0000000..b006de3
--- /dev/null
+++ b/vendor/github.com/ncruces/go-strftime/parser.go
@@ -0,0 +1,107 @@
+package strftime
+
+import "unicode/utf8"
+
+type parser struct {
+	format  func(spec, flag byte) error
+	literal func(byte) error
+}
+
+func (p *parser) parse(fmt string) error {
+	const (
+		initial = iota
+		percent
+		flagged
+		modified
+	)
+
+	var flag, modifier byte
+	var err error
+	state := initial
+	start := 0
+	for i, b := range []byte(fmt) {
+		switch state {
+		default:
+			if b == '%' {
+				state = percent
+				start = i
+				continue
+			}
+			err = p.literal(b)
+
+		case percent:
+			if b == '-' || b == ':' {
+				state = flagged
+				flag = b
+				continue
+			}
+			if b == 'E' || b == 'O' {
+				state = modified
+				modifier = b
+				flag = 0
+				continue
+			}
+			err = p.format(b, 0)
+			state = initial
+
+		case flagged:
+			if b == 'E' || b == 'O' {
+				state = modified
+				modifier = b
+				continue
+			}
+			err = p.format(b, flag)
+			state = initial
+
+		case modified:
+			if okModifier(modifier, b) {
+				err = p.format(b, flag)
+			} else {
+				err = p.literals(fmt[start : i+1])
+			}
+			state = initial
+		}
+
+		if err != nil {
+			if err, ok := err.(formatError); ok {
+				err.setDirective(fmt, start, i)
+				return err
+			}
+			return err
+		}
+	}
+
+	if state != initial {
+		return p.literals(fmt[start:])
+	}
+	return nil
+}
+
+func (p *parser) literals(literal string) error {
+	for _, b := range []byte(literal) {
+		if err := p.literal(b); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+type literalErr string
+
+func (e literalErr) Error() string {
+	return "strftime: unsupported literal: " + string(e)
+}
+
+type formatError struct {
+	message   string
+	directive string
+}
+
+func (e formatError) Error() string {
+	return "strftime: unsupported directive: " + e.directive + " " + e.message
+}
+
+func (e *formatError) setDirective(str string, i, j int) {
+	_, n := utf8.DecodeRuneInString(str[j:])
+	e.directive = str[i : j+n]
+}