Documentation
¶
Overview ¶
Package kpath provides kinded path parsing and navigation.
Kinded paths encode both navigation and structure type in the syntax:
- .field - Object field access
- [index] - Dense array index
- {index} - Sparse array/map index
- .* / [*] / {*} - Wildcards
Usage ¶
// Parse a kinded path
kp, err := kpath.Parse("users[0].name")
// Access path components
seg := kp.LastSegment()
kind := seg.EntryKind() // FieldEntry, ArrayEntry, or SparseArrayEntry
// Navigate
parent := kp.Parent()
child := kp.Append(kpath.Field("email"))
// Compare paths
cmp := kp1.Compare(kp2) // -1, 0, or 1
Path Examples ¶
"users[0].name" // Object → array → object field
"data{3002}.settings" // Object → sparse array → object field
"resources[*].status" // Wildcard matching
Related Packages ¶
- github.com/signadot/tony-format/go-tony/ir - IR representation
Index ¶
- func Compare(a, b string) int
- func Join(prefix string, suffix string) string
- func RSplit(kpath string) (parentPath string, lastSegment string)
- func SegmentFieldName(segment string) (fieldName string, isField bool)
- func Split(kpath string) (firstSegment string, restPath string)
- func SplitAll(kpath string) []string
- type EntryKind
- type KPath
- func (p *KPath) AncestorOrEqual(other *KPath) (anc, eq bool)
- func (p *KPath) Compare(other *KPath) int
- func (p *KPath) EntryKind() EntryKind
- func (p *KPath) IsPrefix(o *KPath) bool
- func (p *KPath) LastSegment() *KPath
- func (p *KPath) MarshalText() ([]byte, error)
- func (p *KPath) Parent() *KPath
- func (p *KPath) SegmentString() string
- func (p *KPath) String() string
- func (p *KPath) Type() *SegmentType
- func (p *KPath) UnmarshalText(d []byte) error
- func (p *KPath) Wild() bool
- type SegmentType
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Join ¶
Join joins a prefix segment with a suffix kinded path. The prefix should be a single segment (field name, [index], or {index}). Returns the combined kinded path string.
Examples:
- Join("a", "b.c") → "a.b.c"
- Join("a", "[0]") → "a[0]"
- Join("[0]", "b") → "[0].b"
- Join("a", "") → "a"
- Join("", "b") → "b"
func RSplit ¶
RSplit splits a kinded path into the parent path and the last segment. Returns the parent path (everything except the last segment) and the last segment. Panics if the path cannot be parsed (invalid kinded path syntax).
Examples:
- RSplit("a.b.c") → ("a.b", "c")
- RSplit("a[0]") → ("a", "[0]")
- RSplit("[0].b") → ("[0]", "b")
- RSplit("{13}.c") → ("{13}", "c")
- RSplit("a") → ("", "a")
- RSplit("") → ("", "")
The last segment is returned as a string representation:
- Field: "a" or "'field name'" (quoted if needed)
- Dense array: "[0]"
- Sparse array: "{0}"
func SegmentFieldName ¶
SegmentFieldName extracts the field name from a segment string. Returns the unquoted field name and true if the segment is a field segment. Returns false if the segment is not a field (e.g., array index "[0]", sparse index "{0}", wildcard "*").
Examples:
- SegmentFieldName("a") → ("a", true)
- SegmentFieldName("'field name'") → ("field name", true)
- SegmentFieldName("\"field name\"") → ("field name", true)
- SegmentFieldName("[0]") → ("", false)
- SegmentFieldName("{0}") → ("", false)
- SegmentFieldName("*") → ("", false)
func Split ¶
Split splits a kinded path into the first segment and the remaining path. Returns the first segment as a string (suitable for use as a map key) and the rest of the path. Panics if the path cannot be parsed (invalid kinded path syntax).
Examples:
- Split("a.b.c") → ("a", "b.c")
- Split("[0].b") → ("[0]", "b")
- Split("{13}.c") → ("{13}", "c")
- Split("a") → ("a", "")
- Split("") → ("", "")
The first segment is returned as a string representation:
- Field: "a" or "'field name'" (quoted if needed)
- Dense array: "[0]"
- Sparse array: "{0}"
func SplitAll ¶
SplitAll splits a kinded path into all segments from root to leaf. Returns a slice of segment strings, each representing a valid top-level kpath. Panics if the path cannot be parsed (invalid kinded path syntax).
Examples:
- SplitAll("a.b.c") → ["a", "b", "c"]
- SplitAll("[0].b") → ["[0]", "b"]
- SplitAll("{13}.c") → ["{13}", "c"]
- SplitAll("a") → ["a"]
- SplitAll("") → []
Each segment is a valid top-level kpath that will parse:
- Field: "a" or "'field name'" (quoted if needed)
- Dense array: "[0]" or "[*]"
- Sparse array: "{0}" or "{*}"
- Field wildcard: "*" (top-level) or ".*" (nested)
Types ¶
type KPath ¶
type KPath struct {
Field *string // Object field name (e.g., "a", "b") - similar to Path.Field
FieldAll bool // Object field wildcard .* - matches all fields
Index *int // Dense array index (e.g., 0, 1) - similar to Path.Index
IndexAll bool // Dense array wildcard [*] - similar to Path.IndexAll
SparseIndex *int // Sparse array index (e.g., 0, 42) - for {n} syntax
SparseIndexAll bool // Sparse array wildcard {*} - matches all sparse indices
Next *KPath // Next segment in path (nil for leaf) - similar to Path.Next
}
KPath represents a kinded path (similar to Path but for kinded syntax). Kinded paths encode node kinds in the path syntax itself:
- "a.b" → Object accessed via ".b" (a is ObjectType)
- "a.*" → Object field wildcard (matches all fields)
- "a[0]" → Dense Array accessed via "[0]" (a is ArrayType)
- "a[*]" → Dense Array wildcard (matches all elements)
- "a{0}" → Sparse Array accessed via "{0}" (a is SparseArrayType)
- "a{*}" → Sparse Array wildcard (matches all sparse indices)
Future: Support for !key(path) objects:
- "a.b(<value>)[2].fred" → Object with !key path value
func Parse ¶
Parse parses a kinded path string into a KPath structure.
Kinded path syntax:
- "a.b" → Object accessed via ".b"
- "a[0]" → Dense Array accessed via "[0]"
- "a[*]" → Dense Array wildcard (matches all elements)
- "a{0}" → Sparse Array accessed via "{0}"
Examples:
- "a.b.c" → Object path with 3 segments
- "a[0][1]" → Dense array path with 3 segments
- "a[*].b" → Array wildcard then object
- "a{0}.b" → Sparse array then object
- "" → Root path (returns nil)
Returns an error if the path syntax is invalid.
func SparseIndex ¶
func (*KPath) AncestorOrEqual ¶
AncestorOrEqual returns true if kp is an ancestor of other. "a" is ancestor of "a.b", "a.b[0]", etc.
func (*KPath) Compare ¶
Compare compares two paths lexicographically. Returns -1 if p < other, 0 if p == other, 1 if p > other.
func (*KPath) LastSegment ¶
LastSegment returns the last segment as a single-segment KPath.
func (*KPath) MarshalText ¶
func (*KPath) Parent ¶
Parent returns the parent path (all but last segment). Returns nil for root or single-segment paths.
func (*KPath) SegmentString ¶
SegmentString returns the canonical string representation of this single segment. Unlike String(), this only returns the current segment, not the entire path. Examples:
- KPath{Field: &"a"} → "a"
- KPath{Field: &"field name"} → "'field name'" (quoted if needed)
- KPath{Index: &0} → "[0]"
- KPath{SparseIndex: &42} → "{42}"
- KPath{FieldAll: true} → "*"
- KPath{IndexAll: true} → "[*]"
- KPath{SparseIndexAll: true} → "{*}"
func (*KPath) String ¶
String returns the kinded path string representation of this KPath. Example:
KPath{Field: &"a", Next: &KPath{Field: &"b", ...}} → "a.b"
KPath{Field: &"a", Next: &KPath{FieldAll: true, ...}} → "a.*"
KPath{Field: &"a", Next: &KPath{Index: &0, ...}} → "a[0]"
KPath{Field: &"a", Next: &KPath{IndexAll: true, ...}} → "a[*]"
KPath{Field: &"a", Next: &KPath{SparseIndex: &42, ...}} → "a{42}"
KPath{Field: &"a", Next: &KPath{SparseIndexAll: true, ...}} → "a{*}"
func (*KPath) Type ¶
func (p *KPath) Type() *SegmentType