Skip to content

asciimoth/persist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

persist

Go Reference

persist is a Go library for immutable, persistent JSON-like data structures. It provides compact values, scalar-keyed persistent maps, persistent vectors, and mixed map/vector path updates.

Use it when you want cheap snapshots, undo/redo state, copy-on-write configuration or policy trees, request-local document edits, or concurrent reads with independently derived versions.

Install

go get github.com/asciimoth/persist

Value Model

Value can hold:

  • nil
  • int64
  • float64
  • string
  • bool
  • Map
  • Vector

Key can hold only scalar key types: nil, int64, float64, string, and bool. Maps and vectors cannot be map keys.

Zero values are valid: Value{} is nil, Key{} is the nil key, Map{} is an empty map, and Vector{} is an empty vector.

Usage

package main

import (
	"fmt"

	"github.com/asciimoth/persist"
)

func main() {
	profile := persist.NewMap().
		Assoc(persist.KString("name"), persist.String("Ada")).
		Assoc(persist.KString("visits"), persist.Int(1))

	root := persist.MapValue(persist.NewMap().
		Assoc(persist.KString("profile"), persist.MapValue(profile)))

	next, err := persist.SetIn(
		root,
		persist.Int(2),
		persist.MapKey(persist.KString("profile")),
		persist.MapKey(persist.KString("visits")),
	)
	if err != nil {
		panic(err)
	}

	oldVisits, _ := persist.GetIn(root, persist.MapKey(persist.KString("profile")), persist.MapKey(persist.KString("visits")))
	newVisits, _ := persist.GetIn(next, persist.MapKey(persist.KString("profile")), persist.MapKey(persist.KString("visits")))
	oldN, _ := oldVisits.Int64()
	newN, _ := newVisits.Int64()

	fmt.Println(oldN, newN)
}

Every update returns a new root and leaves older roots unchanged. Unchanged subtrees are shared internally.

JSON

Use persist.FromJSON to decode ordinary JSON into a Value, and use Value.ToJSON, Map.ToJSON, or Vector.ToJSON to encode it again. Value, Map, and Vector also implement the standard encoding/json marshal and unmarshal interfaces.

root, err := persist.FromJSON([]byte(`{"items":[{"score":10}]}`))
if err != nil {
	panic(err)
}
data, err := root.ToJSON()

JSON objects decode as maps with string keys. Maps that use nil, integer, float, or bool keys are valid in memory but cannot be encoded as JSON objects. Integer-looking JSON numbers decode as Int when they fit in int64; decimal/exponent numbers decode as Float.

API Notes

  • Map.Assoc and Map.Dissoc return new maps.
  • Vector.Set, Vector.Append, and Vector.Pop return new vectors.
  • Map.All and Vector.All return standard Go iterators over immediate entries.
  • Map.Walk and Vector.Walk return standard Go iterators over nested map/vector trees with paths expressed as Step values.
  • GetIn and SetIn operate on nested map/vector paths.
  • FromJSON and ToJSON convert ordinary JSON documents to and from Value.
  • NewReadOnlyMapConfig, NewReadOnlyVectorConfig, and NewReadOnlyConfig expose read-only views over string-keyed map/vector trees that implement github.com/asciimoth/configer/configer.Config.
  • Value.Equal, Map.Equal, and Vector.Equal perform deep semantic equality checks.
  • Key.Equal, Step.Equal, and Kind.Equal compare keys, path steps, and kinds.
  • Value.Same is shallow: scalars compare by value, strings by content, and maps/vectors by identity. It is not deep equality.
  • Map iteration order is unspecified. Vector iteration is by ascending index.
  • Float map keys normalize -0 to +0 and all NaN payloads to a canonical NaN. Float leaf values preserve exact IEEE-754 bits.
  • String and KString retain the supplied string backing storage without copying. Use StringClone and KStringClone when long-lived values should avoid retaining a larger original buffer.

License

Files in this repository are distributed under the CC0 license.

CC0
To the extent possible under law, ASCIIMoth has waived all copyright and related or neighboring rights to persist.

About

Persistent data structures for go

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors