Categorygithub.com/tliron/go-ard
modulepackage
0.2.17
Repository: https://github.com/tliron/go-ard.git
Documentation: pkg.go.dev

# README

Agnostic Raw Data (ARD) for Go

License Go Reference Go Report Card

A library to work with non-schematic data and consume it from various standard formats.

What is ARD? See here. Some people gloss it as "JSON", but that's misleading and ultimately unhelpful because JSON is merely a representation format for the data, and a rather limited format at that (e.g. it does not preserve the distinction between integers and floats).

This library supports several representation formats for ARD:

It is also implemented in Python.

And check out the ardconv ARD conversion tool.

Features

Read ARD from any Go Reader or decode from strings:

import (
	"fmt"
	"strings"
	"github.com/tliron/go-ard"
)

var yamlRepresentation = `
first:
  property1: Hello
  property2: 1.2
  property3:
  - 1
  - 2
  - second:
      property1: World
`

func main() {
	if value, _, err := ard.Read(strings.NewReader(yamlRepresentation), "yaml", false); err == nil {
		fmt.Printf("%v\n", value)
	}
}

Some formats (only YAML currently) support a Locator interface for finding the line and column for each data element, very useful for error messages:

var yamlRepresentation = `
first:
  property1: Hello
  property2: 1.2
  property3: [ 1, 2 ]
`

func main() {
	if _, locator, err := ard.Decode(yamlRepresentation, "yaml", true); err == nil {
		if locator != nil {
			if line, column, ok := locator.Locate(
				ard.NewMapPathElement("first"),
				ard.NewFieldPathElement("property3"),
				ard.NewListPathElement(0),
			); ok {
				fmt.Printf("%d, %d\n", line, column) // 5, 16
			}
		}
	}
}

Unmarshal ARD into Go structs:

var data = ard.Map{ // "ard.Map" is an alias for "map[any]any"
	"FirstName": "Gordon",
	"lastName":  "Freeman",
	"nicknames": ard.List{"Tigerbalm", "Stud Muffin"}, // "ard.List" is an alias for "[]any"
	"children": ard.List{
		ard.Map{
			"FirstName": "Bilbo",
		},
		ard.StringMap{ // "ard.StringMap" is an alias for "map[string]any"
			"FirstName": "Frodo",
		},
		nil,
	},
}

type Person struct {
	FirstName string    // property name will be used as field name
	LastName  string    `ard:"lastName"`   // "ard" tags work like familiar "json" and "yaml" tags
	Nicknames []string  `yaml:"nicknames"` // actually, go-ard will fall back to "yaml" tags by default
	Children  []*Person `json:"children"`  // ...and "json" tags, too
}

func main() {
	reflector := ard.NewReflector() // configurable; see documentation
	var p Person
	if err := reflector.Pack(data, &p); err == nil {
		fmt.Printf("%+v\n", p)
	}
}

Copy, merge, and compare:

func main() {
	data_ := ard.Copy(data).(ard.Map)
	fmt.Printf("%t\n", ard.Equals(data, data_))
	ard.Merge(data, ard.Map{"role": "hero", "children": ard.List{"Gollum"}}, true)
	fmt.Printf("%v\n", data)
}

Node-based path traversal:

var data = ard.Map{
	"first": ard.Map{
		"property1": "Hello",
		"property2": ard.StringMap{
			"second": ard.Map{
				"property3": 1}}}}

func main() {
	if p1, ok := ard.With(data).Get("first", "property1").String(); ok {
		fmt.Println(p1)
	}
	if p2, ok := ard.With(data).Get("first", "property2", "second", "property3").ConvertSimilar().Float(); ok {
		fmt.Printf("%f\n", p2)
	}
	if p3, ok := ard.With(data).GetPath("first.property2.second.property3", ".").ConvertSimilar().Float(); ok {
		fmt.Printf("%f\n", p3)
	}
}

By default go-ard reads maps into map[any]any, but you can normalize for either map[any]any or map[string]map (Go's built-in JSON encoder unfortunately requires the latter):

import "encoding/json"

var data = ard.Map{ // remember, these are "map[any]any"
	"person": ard.Map{
		"age": uint(120),
	},
}

func main() {
	if data_, ok := ard.CopyMapsToStringMaps(data); ok { // otherwise "encoding/json" won't be able to encode the "map[any]any"
		json.NewEncoder(os.Stdout).Encode(data_)
	}
}

Introducing the XJSON (eXtended JSON) format that adds support for missing ARD types: integers, unsigned integers, and maps with non-string keys:

var data = ard.Map{
	"person": ard.Map{
		"age": uint(120),
	},
}

func main() {
	if data_, err := ard.PrepareForEncodingXJSON(data, false, nil); err == nil { // will conveniently also normalize to "map[string]any" for "encoding/json" to work
		if j, err := json.Marshal(data_); err == nil {
			fmt.Println(string(j)) // {"map":{"age":{"$ard.uinteger":"120"}}}
			if data__, _, err := ard.Decode(j, "xjson", false); err == nil {
				fmt.Printf("%v\n", data__)
			}
		}
	}
}

# Functions

Converts any [Map] to [StringMap] recursively, ensuring that no [Map] will be present.
Converts any [StringMap] to [Map] recursively, ensuring that no [StringMap] will be present.
Deep copy.
Like [Copy] but converts all [Map] to [StringMap].
Like [Copy] but converts all [StringMap] to [Map].
Decodes supported formats to an ARD [Value].
Decodes CBOR to an ARD [Value].
Decodes JSON to an ARD [Value].
Reads MessagePack from an [io.Reader] and decodes it to an ARD [Value].
Convenience function to parse and render a template and then decode it.
Decodes JSON to an ARD [Value] while interpreting the XJSON extensions.
Decodes XML to an ARD [Value].
Decodes YAML to an ARD [Value].
Checks for deep equality between two ARD values.
No description provided by the author
Returns a canonical name for all supported ARD types, including primitives, [Map], [List], and [time.Time].
Returns true if value is a [bool].
Returns true if value is []byte.
Returns true if value is a [List] ([]any).
Returns true if value is a [Map] (map[any]any).
Returns true if value is nil.
Returns true if value is a string, bool, int64, int32, int16, int8, int, uint64, uint32, uint16, uint8, uint, float64, float32, nil, []byte, or [time.Time].
Returns true if value is a string.
Returns true if value is a [time.Time].
Provides consistent stringification of keys for ARD [StringMap].
Marshals MessagePack with support for "json" field tags.
Deep merge of source value into target value.
No description provided by the author
No description provided by the author
No description provided by the author
MessagePack decoder that supports "json" field tags.
MessagePack encode that supports "json" field tags.
Creates a reflector with default struct field tags: "ard", "yaml", "json".
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Convenience function to convert a string path to keys usable for [Node.Get] and [Node.ForceGet].
Prepares an ARD [Value] for encoding via [xml.Encoder].
Prepares an ARD [Value] for encoding via [xml.Encoder].
Reads and decodes supported formats to ARD.
No description provided by the author
Reads CBOR from an [io.Reader] and decodes it to an ARD [Value].
Reads JSON from an [io.Reader] and decodes it to an ARD [Value].
Reads MessagePack from an [io.Reader] and decodes it to an ARD [Value].
Convenience function to read from a URL.
Reads JSON from an [io.Reader] and decodes it to an ARD [Value] while interpreting the XJSON extensions.
Reads XML from an [io.Reader] and decodes it to an ARD [Value].
Reads YAML from an [io.Reader] and decodes it to an ARD [Value].
Encodes and then decodes the value via a supported format.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Unmarshals MessagePack with support for "json" field tags.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Validates that data is of a supported format.
If base64 is true then the data will first be fully read and decoded from Base64 to bytes.
No description provided by the author
If base64 is true then the data will first be fully read and decoded from Base64 to bytes.
No description provided by the author
No description provided by the author
Deep copy and return a valid ARD value.
Like [ValidCopy] but converts all [Map] to [StringMap].
Like [ValidCopy] but converts all [StringMap] to [Map].
Provides consistent stringification of primitive ARD [Value].
Creates an extractable, convertible, traversable, and modifiable wrapper (a [Node]) for an ARD [Value].

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
JSON schema: https://yaml.org/spec/1.2/spec.html#id2803231.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Failsafe schema: https://yaml.org/spec/1.2/spec.html#id2802346.
Other schemas: https://yaml.org/spec/1.2/spec.html#id2805770.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

This singleton is returned from all node functions when no node is found.
No description provided by the author
No description provided by the author

# Structs

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Interfaces

Structs can implement their own custom packing with this interface.
No description provided by the author
Structs can implement their own custom unpacking with this interface.

# Type aliases

An alias used to signify a list of ARD [Value].
An alias used to signify a map of ARD [Value] in which the key is also a [Value].
No description provided by the author
No description provided by the author
An alias used to signify a map of ARD [Value] in which the key is always string.
No description provided by the author
No description provided by the author
No description provided by the author
An alias used to signify that ARD values are expected, namely primitives, [List], [Map], and [StringMap] nested to any depth.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author