encoding

package
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 9 Imported by: 0

README

encoding

import "github.com/gechr/x/encoding"

Package encoding provides helpers for structured document formats such as JSON and YAML: building field paths for diagnostics and lookup.

Index

type Path

Path is an immutable field path into a structured document (JSON, YAML, ...), built segment by segment for diagnostics and lookup:

NewPath("items").Index(0).Child("foo", "bar").Wildcard() // items[0].foo.bar[*]

Each method allocates a new Path referencing its receiver as parent, so multiple children can safely branch off a shared prefix - handy in recursive document walkers.

A nil *Path is the empty path: it renders as "" and addresses the document itself in lookups. All methods are nil-safe.

type Path struct {
    // contains filtered or unexported fields
}

func NewPath
func NewPath(name string, moreNames ...string) *Path

NewPath returns a Path rooted at name, extended with moreNames as nested children.

Example
p := xencoding.NewPath("items").Index(0).Child("foo", "bar").Wildcard()
fmt.Println(p)

Output:

items[0].foo.bar[*]

func (*Path) Child
func (p *Path) Child(name string, moreNames ...string) *Path

Child returns p extended with name (and moreNames) as nested field segments. Names render in dot notation (.name), or bracket-quoted (["a.b"]) when they contain characters other than letters, digits, _, and -.

Example

Names that cannot appear in dot notation are bracket-quoted automatically.

p := xencoding.NewPath("metadata", "labels").Child("kubernetes.io/hostname")
fmt.Println(p)

Output:

metadata.labels["kubernetes.io/hostname"]

func (*Path) Index
func (p *Path) Index(index int) *Path

Index returns p extended with an array index segment, rendered as [3].

func (*Path) Key
func (p *Path) Key(key string) *Path

Key returns p extended with an explicit key segment, always rendered bracket-quoted (["name"]) even when key would be valid in dot notation. Lookup treats it exactly like Path.Child.

func (*Path) Lookup
func (p *Path) Lookup(doc any) (any, bool)

Lookup resolves p against doc, a document decoded into generic Go values (map[string]any, map[any]any, []any), and returns the value it addresses. It reports false when a segment is missing, an index is out of range, or the path contains a wildcard segment (use Path.LookupAll).

Example
doc := map[string]any{"spec": map[string]any{"replicas": 3}}
v, ok := xencoding.NewPath("spec", "replicas").Lookup(doc)
fmt.Println(v, ok)

Output:

3 true

func (*Path) LookupAll
func (p *Path) LookupAll(doc any) []any

LookupAll resolves p against doc, fanning out at wildcard segments: each Path.Wildcard matches every element of an array in order, or every value of a map in natural key order (see strings.CompareNatural, with ties broken lexically and then by the key's Go type). Values missing a later segment are skipped. Without wildcards the result has at most one value. Returns nil when nothing matches.

Example
doc := map[string]any{"items": []any{
    map[string]any{"name": "a"},
    map[string]any{"name": "b"},
}}
names := xencoding.NewPath("items").Wildcard().Child("name").LookupAll(doc)
fmt.Println(names)

Output:

[a b]

func (*Path) Render
func (p *Path) Render(opts ...RenderOption) string

Render returns the path in dot/bracket notation, e.g. items[0].foo.bar[*]. Names that cannot appear in dot notation are bracket-quoted: spec["a.b"]. Pass WithRoot to prefix a JSONPath-style root marker: $.items[0]. The output is a human-readable diagnostic notation, not strict RFC 9535 JSONPath (bare names are broader, and quoting follows Go syntax).

Example
p := xencoding.NewPath("items").Index(0)
fmt.Println(p.Render())
fmt.Println(p.Render(xencoding.WithRoot()))
fmt.Println(p.Render(xencoding.WithRoot('@')))

Output:

items[0]
$.items[0]
@.items[0]

func (*Path) String
func (p *Path) String() string

String implements fmt.Stringer; it is Path.Render with default options.

func (*Path) Wildcard
func (p *Path) Wildcard() *Path

Wildcard returns p extended with a [*] segment matching every element of an array or every value of a map. Path.LookupAll fans out at wildcard segments; Path.Lookup cannot resolve them.

type RenderOption

RenderOption configures Path.Render.

type RenderOption func(*renderConfig)

func WithRoot
func WithRoot(marker ...rune) RenderOption

WithRoot prefixes the rendered path with a root marker: $ by default ($.items[0]), or marker if given (WithRoot('@') renders @.items[0]).

Documentation

Overview

Package encoding provides helpers for structured document formats such as JSON and YAML: building field paths for diagnostics and lookup.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Path

type Path struct {
	// contains filtered or unexported fields
}

Path is an immutable field path into a structured document (JSON, YAML, ...), built segment by segment for diagnostics and lookup:

NewPath("items").Index(0).Child("foo", "bar").Wildcard() // items[0].foo.bar[*]

Each method allocates a new Path referencing its receiver as parent, so multiple children can safely branch off a shared prefix - handy in recursive document walkers.

A nil `*Path` is the empty path: it renders as `""` and addresses the document itself in lookups. All methods are nil-safe.

func NewPath

func NewPath(name string, moreNames ...string) *Path

NewPath returns a Path rooted at `name`, extended with `moreNames` as nested children.

Example
package main

import (
	"fmt"

	xencoding "github.com/gechr/x/encoding"
)

func main() {
	p := xencoding.NewPath("items").Index(0).Child("foo", "bar").Wildcard()
	fmt.Println(p)
}
Output:
items[0].foo.bar[*]

func (*Path) Child

func (p *Path) Child(name string, moreNames ...string) *Path

Child returns `p` extended with `name` (and `moreNames`) as nested field segments. Names render in dot notation (`.name`), or bracket-quoted (`["a.b"]`) when they contain characters other than letters, digits, `_`, and `-`.

Example

Names that cannot appear in dot notation are bracket-quoted automatically.

package main

import (
	"fmt"

	xencoding "github.com/gechr/x/encoding"
)

func main() {
	p := xencoding.NewPath("metadata", "labels").Child("kubernetes.io/hostname")
	fmt.Println(p)
}
Output:
metadata.labels["kubernetes.io/hostname"]

func (*Path) Index

func (p *Path) Index(index int) *Path

Index returns `p` extended with an array index segment, rendered as `[3]`.

func (*Path) Key

func (p *Path) Key(key string) *Path

Key returns `p` extended with an explicit key segment, always rendered bracket-quoted (`["name"]`) even when `key` would be valid in dot notation. Lookup treats it exactly like Path.Child.

func (*Path) Lookup

func (p *Path) Lookup(doc any) (any, bool)

Lookup resolves `p` against `doc`, a document decoded into generic Go values (`map[string]any`, `map[any]any`, `[]any`), and returns the value it addresses. It reports false when a segment is missing, an index is out of range, or the path contains a wildcard segment (use Path.LookupAll).

Example
package main

import (
	"fmt"

	xencoding "github.com/gechr/x/encoding"
)

func main() {
	doc := map[string]any{"spec": map[string]any{"replicas": 3}}
	v, ok := xencoding.NewPath("spec", "replicas").Lookup(doc)
	fmt.Println(v, ok)
}
Output:
3 true

func (*Path) LookupAll

func (p *Path) LookupAll(doc any) []any

LookupAll resolves `p` against `doc`, fanning out at wildcard segments: each Path.Wildcard matches every element of an array in order, or every value of a map in natural key order (see github.com/gechr/x/strings.CompareNatural, with ties broken lexically and then by the key's Go type). Values missing a later segment are skipped. Without wildcards the result has at most one value. Returns nil when nothing matches.

Example
package main

import (
	"fmt"

	xencoding "github.com/gechr/x/encoding"
)

func main() {
	doc := map[string]any{"items": []any{
		map[string]any{"name": "a"},
		map[string]any{"name": "b"},
	}}
	names := xencoding.NewPath("items").Wildcard().Child("name").LookupAll(doc)
	fmt.Println(names)
}
Output:
[a b]

func (*Path) Render

func (p *Path) Render(opts ...RenderOption) string

Render returns the path in dot/bracket notation, e.g. `items[0].foo.bar[*]`. Names that cannot appear in dot notation are bracket-quoted: `spec["a.b"]`. Pass WithRoot to prefix a JSONPath-style root marker: `$.items[0]`. The output is a human-readable diagnostic notation, not strict RFC 9535 JSONPath (bare names are broader, and quoting follows Go syntax).

Example
package main

import (
	"fmt"

	xencoding "github.com/gechr/x/encoding"
)

func main() {
	p := xencoding.NewPath("items").Index(0)
	fmt.Println(p.Render())
	fmt.Println(p.Render(xencoding.WithRoot()))
	fmt.Println(p.Render(xencoding.WithRoot('@')))
}
Output:
items[0]
$.items[0]
@.items[0]

func (*Path) String

func (p *Path) String() string

String implements fmt.Stringer; it is Path.Render with default options.

func (*Path) Wildcard

func (p *Path) Wildcard() *Path

Wildcard returns `p` extended with a `[*]` segment matching every element of an array or every value of a map. Path.LookupAll fans out at wildcard segments; Path.Lookup cannot resolve them.

type RenderOption

type RenderOption func(*renderConfig)

RenderOption configures Path.Render.

func WithRoot

func WithRoot(marker ...rune) RenderOption

WithRoot prefixes the rendered path with a root marker: `$` by default (`$.items[0]`), or `marker` if given (`WithRoot('@')` renders `@.items[0]`).

Jump to

Keyboard shortcuts

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