...

Package vson

import "git.sr.ht/~roselandgoose/vson"
Overview
Index

Overview ▾

Package vson provides an ergonomic way to version JSON objects without having to explicitly defining schemas.

Usage

1. Wrap your data inside a JSON object like so:

{
	"version": 1,
	"raw": {
		"my_actual": "object"
	}
}

2. Create a vson.Version inside a map with a pointer to a nil value of your struct:

vers := map[uint]vson.Version {
	1: vson.Version {
		Ptr: new(my_type),
	},
}

Now you can decode JSON streams using a vson.Versioner:

vsr := vson.NewVersioner(vers)
v := new(my_type)
err := vsr.Decode(<json stream>, v)//

When you make a non backwards-compatible change

1. Rename your old object type:

type my_type_v1 struct {
	...
}

2. Define a function which migrates a pointer to the old struct to the new version:

func v1_to_2(in any) (any, error) {
	v1 := in.(*my_type_v1)
	v2 := &my_type {
		...
	}
    return v2, nil
}

3. Update the vson.Version entry in your map with the new function:

vers := map[uint]vson.Version {
	1: vson.Version {
		Ptr: new(my_type_v1),
		Migrator: v1_to_2,
	},
}

4. Create a new vson.Version in your map for the new version.

vers := map[uint]vson.Version {
	1: vson.Version {
		Ptr: new(my_type_v1),
		Migrator: v1_to_2,
	},
	2: vson.Version {
		Ptr: new(my_type),
	},
}

Now your vson.Versioner will accept JSON streams of either version and return the latest version:

vsr := vson.NewVersioner(vers)
v := new(my_type)
err := vsr.Decode(<json stream>, v)

type Migrator

type Migrator func(any) (any, error)

type Version

type Version struct {
    Ptr      any
    Migrator Migrator
}

type Versioner

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

func NewVersioner

func NewVersioner(versions map[uint]Version) (*Versioner, error)

func (*Versioner) Decode

func (vsr *Versioner) Decode(r io.Reader, v any) error

Decode works similarly to (and wraps) a json.Decoder. It reads a JSON stream representing any known Version and decodes it into the latest version.

func (*Versioner) Encode

func (vsr *Versioner) Encode(w io.Writer, v any) error

Encode works similarly to (and wraps) a json.Encoder. It encodes v with the latest version number.