kpath

package
v0.0.20 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2025 License: Apache-2.0 Imports: 6 Imported by: 0

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
  • github.com/signadot/tony-format/go-tony/ir - IR representation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Compare

func Compare(a, b string) int

func Join

func Join(prefix string, suffix string) string

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

func RSplit(kpath string) (parentPath string, lastSegment string)

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

func SegmentFieldName(segment string) (fieldName string, isField bool)

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

func Split(kpath string) (firstSegment string, restPath string)

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

func SplitAll(kpath string) []string

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 EntryKind

type EntryKind int
const (
	FieldEntry EntryKind = iota
	ArrayEntry
	SparseArrayEntry
)

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 Field

func Field(f string) *KPath

func Index

func Index(i int) *KPath

func Parse

func Parse(kpath string) (*KPath, error)

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 SparseIndex(i int) *KPath

func (*KPath) AncestorOrEqual

func (p *KPath) AncestorOrEqual(other *KPath) (anc, eq bool)

AncestorOrEqual returns true if kp is an ancestor of other. "a" is ancestor of "a.b", "a.b[0]", etc.

func (*KPath) Compare

func (p *KPath) Compare(other *KPath) int

Compare compares two paths lexicographically. Returns -1 if p < other, 0 if p == other, 1 if p > other.

func (*KPath) EntryKind

func (p *KPath) EntryKind() EntryKind

func (*KPath) IsPrefix

func (p *KPath) IsPrefix(o *KPath) bool

func (*KPath) LastSegment

func (p *KPath) LastSegment() *KPath

LastSegment returns the last segment as a single-segment KPath.

func (*KPath) MarshalText

func (p *KPath) MarshalText() ([]byte, error)

func (*KPath) Parent

func (p *KPath) Parent() *KPath

Parent returns the parent path (all but last segment). Returns nil for root or single-segment paths.

func (*KPath) SegmentString

func (p *KPath) SegmentString() string

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

func (p *KPath) String() 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

func (*KPath) UnmarshalText

func (p *KPath) UnmarshalText(d []byte) error

func (*KPath) Wild

func (p *KPath) Wild() bool

type SegmentType

type SegmentType struct {
	EntryKind EntryKind
	Wild      bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL