orderedobject

package module
v0.2.13 Latest Latest
Warning

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

Go to latest
Published: May 1, 2026 License: MIT Imports: 7 Imported by: 0

README

orderedobject

A generic ordered JSON object for Go that preserves insertion order during mutation, iteration, and JSON encoding

Features

  • Ordered keys: Preserve top-level insertion order when encoding JSON.
  • Generic values: Store any or concrete types with the same API.
  • Stable updates: Updating an existing key keeps its original position.
  • Streaming hooks: Use MarshalJSONTo and UnmarshalJSONFrom for token-based JSON work.
  • Map bridges: Convert to and from map[string]V when order does not matter.
  • Runnable examples: Explore focused programs under examples/.

Installation

Requires Go 1.26+.

go get github.com/kaptinlin/orderedobject

Quick Start

package main

import (
	"fmt"
	"log"

	"github.com/kaptinlin/orderedobject"
)

func main() {
	person := orderedobject.NewObject[any]().
		Set("name", "Alice").
		Set("age", 30).
		Set("city", "New York")

	data, err := person.ToJSON()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(data))
}

Output:

{"name":"Alice","age":30,"city":"New York"}

API Overview

API Purpose
NewObject[V](capacity...) Create a new ordered object with optional capacity.
FromMap[V](m) Build an object from a map; resulting order follows Go's map iteration order.
FromJSON[V](data) Decode a JSON object while preserving member order.
Set, Get, Has, Delete Mutate and query keys.
Keys, Values, Entries, ForEach Iterate in insertion order.
Clone Copy the entries slice without deep-copying stored values.
ToMap Convert to a plain map and drop ordering semantics.
ToJSON, MarshalJSON, MarshalJSONTo Encode ordered content to JSON.
UnmarshalJSON, UnmarshalJSONFrom Decode ordered content from JSON.

Examples

Preserve order while updating values
obj := orderedobject.NewObject[int]().
	Set("first", 1).
	Set("second", 2)

obj.Set("first", 99)

fmt.Println(obj.Keys())
// [first second]
Use concrete value types
type User struct {
	Name string
	Age  int
}

users := orderedobject.NewObject[User]().
	Set("alice", User{Name: "Alice", Age: 30}).
	Set("bob", User{Name: "Bob", Age: 25})

user, _ := users.Get("alice")
fmt.Println(user.Name)
// Alice
Run the bundled examples
go run ./examples/basic
go run ./examples/json
go run ./examples/nested

See examples/README.md for the full example list.

Development

task test
task lint

For development guidelines, see AGENTS.md.

Contributing

Run task fmt, task test, and task lint before sending changes.

License

This project is licensed under the MIT License. See LICENSE for details.

Documentation

Overview

Package orderedobject provides an ordered JSON object that preserves key insertion order during JSON marshaling and unmarshaling.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrExpectedObjectStart is returned when the next JSON token is not '{'.
	ErrExpectedObjectStart = errors.New("expected object start")
	// ErrExpectedStringKey is returned when the next JSON token is not a string key.
	ErrExpectedStringKey = errors.New("expected string key")
)

Functions

This section is empty.

Types

type Entry

type Entry[V any] struct {
	// Key is the object member name.
	Key string
	// Value is the value associated with Key.
	Value V
}

Entry holds one key-value pair in an Object.

type Object

type Object[V any] struct {
	// contains filtered or unexported fields
}

Object stores key-value pairs in insertion order.

func FromJSON

func FromJSON[V any](data []byte) (*Object[V], error)

FromJSON decodes data into an Object, preserving key order from the input. FromJSON returns an error if data is not valid JSON or does not encode an object.

func FromMap

func FromMap[V any](m map[string]V) *Object[V]

FromMap returns an Object containing the entries in m. The resulting entry order matches Go's randomized map iteration order.

func NewObject

func NewObject[V any](capacity ...int) *Object[V]

NewObject returns an Object with optional initial capacity.

func (*Object[V]) Clone

func (o *Object[V]) Clone() *Object[V]

Clone returns a shallow copy of o.

func (*Object[V]) Delete

func (o *Object[V]) Delete(key string) *Object[V]

Delete removes key and returns o. Delete is a no-op if key is not present.

func (*Object[V]) Entries

func (o *Object[V]) Entries() []Entry[V]

Entries returns a copy of o's entries in insertion order.

func (*Object[V]) ForEach

func (o *Object[V]) ForEach(fn func(key string, value V))

ForEach calls fn for each entry in insertion order.

func (*Object[V]) Get

func (o *Object[V]) Get(key string) (V, bool)

Get returns the value for key and whether key is present. If key is not present, Get returns the zero value of V and false.

func (*Object[V]) Has

func (o *Object[V]) Has(key string) bool

Has reports whether key is present.

func (*Object[V]) Keys

func (o *Object[V]) Keys() []string

Keys returns a new slice of keys in insertion order.

func (*Object[V]) Len added in v0.2.4

func (o *Object[V]) Len() int

Len returns the number of entries in o.

func (*Object[V]) MarshalJSON

func (o *Object[V]) MarshalJSON() ([]byte, error)

MarshalJSON returns the JSON encoding of o.

func (*Object[V]) MarshalJSONTo

func (o *Object[V]) MarshalJSONTo(enc *jsontext.Encoder) error

MarshalJSONTo writes the JSON encoding of o to enc. Nested map values are encoded with deterministic key order.

func (*Object[V]) Set

func (o *Object[V]) Set(key string, value V) *Object[V]

Set stores value under key and returns o. If key already exists, Set updates its value without changing its position.

func (*Object[V]) ToJSON

func (o *Object[V]) ToJSON() ([]byte, error)

ToJSON returns the JSON encoding of o.

Example
package main

import (
	"fmt"

	"github.com/kaptinlin/orderedobject"
)

func main() {
	person := orderedobject.NewObject[any]().
		Set("name", "Alice").
		Set("age", 30).
		Set("city", "New York")

	data, err := person.ToJSON()
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(data))
}
Output:
{"name":"Alice","age":30,"city":"New York"}

func (*Object[V]) ToMap

func (o *Object[V]) ToMap() map[string]V

ToMap returns a new map containing o's entries. The returned map does not preserve insertion order.

func (*Object[V]) UnmarshalJSON

func (o *Object[V]) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a JSON object into o.

func (*Object[V]) UnmarshalJSONFrom

func (o *Object[V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error

UnmarshalJSONFrom decodes a JSON object from dec into o. UnmarshalJSONFrom replaces any existing entries in o.

func (*Object[V]) Values

func (o *Object[V]) Values() []V

Values returns a new slice of values in insertion order.

type OrderedMarshaler added in v0.1.2

type OrderedMarshaler interface {
	// MarshalJSONTo writes the JSON encoding of the value to enc.
	MarshalJSONTo(enc *jsontext.Encoder) error
}

OrderedMarshaler marshals a value to JSON while preserving key order.

Directories

Path Synopsis
examples
array command
basic command
error command
json command
map command
nested command
type command
internal

Jump to

Keyboard shortcuts

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