package walk import ( "fmt" "strings" ) type PathSegment interface {} type Value interface { value() Debug() string } type NullValue struct{} func (_ NullValue) value() {} func (_ NullValue) Debug() string { return "null" } type BoolValue bool func (_ BoolValue) value() {} func (b BoolValue) Debug() string { if b { return "true" } return "false" } type NumberValue float64 func (_ NumberValue) value() {} func (n NumberValue) Debug() string { return fmt.Sprintf("%v", float64(n)) } type RuneValue rune func (_ RuneValue) value() {} func (r RuneValue) Debug() string { return string(r) } type StringValue string func (_ StringValue) value() {} func (s StringValue) Debug() string { return fmt.Sprintf("%q", string(s)) } type ArrayElement struct { Index int Value Value } type ArrayValue []ArrayElement func (_ ArrayValue) value() {} func (array ArrayValue) Debug() string { builder := strings.Builder{} builder.WriteRune('[') var sep string for _, element := range array { builder.WriteString(sep) builder.WriteString(fmt.Sprintf("%v", element.Index)) builder.WriteString(": ") builder.WriteString(element.Value.Debug()) sep = ", " } builder.WriteRune(']') return builder.String() } type MapElement struct { Key string Value Value } type MapValue []MapElement func (_ MapValue) value() {} func (m MapValue) Debug() string { builder := strings.Builder{} builder.WriteRune('{') var sep string for _, element := range m { builder.WriteString(sep) builder.WriteString(fmt.Sprintf("%q", element.Key)) builder.WriteString(": ") builder.WriteString(element.Value.Debug()) sep = ", " } builder.WriteRune('}') return builder.String() } type WalkItem struct { Value Value Start, PrevStart, End, NextEnd bool } func (item WalkItem) Debug() string { builder := strings.Builder{} if item.Start { builder.WriteRune('a') } if item.PrevStart { builder.WriteRune('A') } if item.NextEnd { builder.WriteRune('Z') } if item.End { builder.WriteRune('z') } builder.WriteString(item.Value.Debug()) return builder.String() }