orderedobject

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2025 License: MIT Imports: 5 Imported by: 0

README

OrderedObject

An ordered JSON object implementation that preserves insertion order, designed to work with github.com/go-json-experiment/json (Go's experimental encoding/json v2).

Table of Contents

Features

  • Preserves key insertion order when marshalling to JSON
  • Generic implementation that can store any type of value
  • Simple API with method chaining
  • Compatible with go-json-experiment/json
  • Rich set of constructors and utility methods

Installation

go get github.com/kaptinlin/orderedobject

Quick Start

package main

import (
	"fmt"

	"github.com/kaptinlin/orderedobject"
	json "github.com/go-json-experiment/json"
)

func main() {
	// Create and populate an ordered object
	person := orderedobject.NewObject[any]().
		Set("name", "John").
		Set("age", 30).
		Set("city", "New York")
	
	// Convert to JSON (order preserved)
	data, _ := person.ToJSON()
	fmt.Println(string(data))
	// Output: {"name":"John","age":30,"city":"New York"}
}

Usage Examples

Basic Operations
// Create and manipulate objects
obj := orderedobject.NewObject[any]().
	Set("a", 1).
	Set("b", 2).
	Set("c", 3)

// Get values
if value, found := obj.Get("a"); found {
	fmt.Println("Value:", value)
}

// Check existence
if obj.Has("b") {
	fmt.Println("Key 'b' exists")
}

// Delete keys
obj.Delete("c")

// Iterate through entries
obj.ForEach(func(key string, value any) {
	fmt.Printf("%s: %v\n", key, value)
})

// Get all entries
entries := obj.Entries()
for _, entry := range entries {
	fmt.Printf("%s: %v\n", entry.Key, entry.Value)
}

// Clone object
clone := obj.Clone()
JSON Operations
// Create from JSON
jsonData := []byte(`{"name":"John","age":30}`)
obj, err := orderedobject.FromJSON[any](jsonData)

// Convert to JSON (three ways)
// 1. Using ToJSON (recommended)
data1, _ := obj.ToJSON()

// 2. Using json.Marshal
data2, _ := json.Marshal(obj)

// 3. Via map (order not preserved)
m := obj.ToMap()
data3, _ := json.Marshal(m)

// Nested objects
address := orderedobject.NewObject[any]().
	Set("street", "123 Main St").
	Set("zipcode", "10001")

person := orderedobject.NewObject[any]().
	Set("name", "Alice").
	Set("address", address)

data, _ := person.ToJSON()
// Output: {"name":"Alice","address":{"street":"123 Main St","zipcode":"10001"}}
Map Operations
// Create from map
m := map[string]any{
	"name": "John",
	"age":  30,
}
obj := orderedobject.FromMap(m)

// Convert to map (order not preserved)
mapData := obj.ToMap()
Type Safety
// Using concrete types
type User struct {
	Name string
	Age  int
}

// Create type-safe object
users := orderedobject.NewObject[User]().
	Set("user1", User{Name: "John", Age: 30}).
	Set("user2", User{Name: "Alice", Age: 25})

// Type-safe value retrieval
if user, found := users.Get("user1"); found {
	fmt.Printf("User: %s, Age: %d\n", user.Name, user.Age)
}

API Reference

Types
  • Entry[V any]: Represents a key-value pair
  • Object[V any]: An ordered collection of key-value pairs
Functions
  • NewObject[V any](capacity ...int) *Object[V]: Creates a new ordered object
  • FromMap[V any](m map[string]V) *Object[V]: Creates an ordered object from a map
  • FromJSON[V any](data []byte) (*Object[V], error): Creates an ordered object from JSON
Methods
  • Set(key string, value V) *Object[V]: Sets a key-value pair
  • Get(key string) (V, bool): Gets a value by key
  • Has(key string) bool: Checks if a key exists
  • Delete(key string) *Object[V]: Removes a key-value pair
  • Length() int: Returns the number of key-value pairs
  • ForEach(fn func(key string, value V)): Iterates through key-value pairs
  • Clone() *Object[V]: Creates a deep copy of the object
  • Entries() []Entry[V]: Returns all key-value pairs
  • ToMap() map[string]V: Converts to a standard Go map
  • ToJSON() ([]byte, error): Converts to JSON
  • MarshalJSON() ([]byte, error): Implements json.Marshaler

FAQ

Q: Why choose go-json-experiment/json over the standard library?

A: go-json-experiment/json provides better performance and more features while maintaining compatibility with the standard library.

Q: Does it support custom JSON tags?

A: Yes, it supports standard struct tags like json:"field_name".

Q: How does it handle key order?

A: The library preserves the insertion order of keys when marshalling to JSON, unlike standard Go maps.

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feat/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add amazing feature')
  4. Push to the branch (git push origin feat/amazing-feature)
  5. Open a Pull Request

Please ensure your code:

  • Includes appropriate tests
  • Follows Go code conventions
  • Updates relevant documentation

License

MIT

Documentation

Overview

Package orderedobject provides an ordered JSON object implementation designed to work with github.com/go-json-experiment/json.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrExpectedObjectStart is returned when the JSON token is not an object start
	ErrExpectedObjectStart = errors.New("expected object start")
	// ErrExpectedStringKey is returned when the 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   string
	Value V
}

Entry represents a key-value pair.

type Object

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

Object is an ordered JSON object that preserves insertion order.

func FromJSON

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

FromJSON parses a JSON string into an ordered object. The order of keys will be preserved as in the JSON string.

func FromMap

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

FromMap creates an ordered object from a map. The order of the keys will be determined by the map iteration order.

func NewObject

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

NewObject returns an ordered object with optional pre-allocated capacity.

func (*Object[V]) Clone

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

Clone returns a deep copy of the ordered object.

func (*Object[V]) Delete

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

Delete removes a key-value pair from the ordered object. If the key does not exist, it does nothing. Returns the object for chaining.

func (*Object[V]) Entries

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

Entries returns all key-value pairs in the ordered object.

func (*Object[V]) ForEach

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

ForEach executes a function for each key-value pair in the ordered object.

func (*Object[V]) Get

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

Get returns the value for a key and whether the key exists. If the key does not exist, it returns the zero value and false.

func (*Object[V]) Has

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

Has returns whether the key exists in the ordered object.

func (*Object[V]) Keys

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

Keys returns all keys in the ordered object.

func (*Object[V]) Length

func (object *Object[V]) Length() int

Length returns the number of key-value pairs in the ordered object.

func (*Object[V]) MarshalJSON

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

MarshalJSON encodes the ordered object as JSON.

func (*Object[V]) MarshalJSONTo

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

MarshalJSONTo encodes the ordered object to a JSON encoder.

func (*Object[V]) Set

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

Set sets the value for a key in the ordered object. If the key already exists, its value is updated. Otherwise, the key-value pair is appended to the end. Returns the object for chaining.

func (*Object[V]) ToJSON

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

ToJSON converts the ordered object to a JSON byte slice. This is a convenience method that internally uses json.Marshal.

func (*Object[V]) ToMap

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

ToMap converts the ordered object to a standard Go map. The returned map will not preserve the insertion order.

func (*Object[V]) UnmarshalJSON

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

UnmarshalJSON decodes a JSON object into the ordered object.

func (*Object[V]) UnmarshalJSONFrom

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

UnmarshalJSONFrom decodes a JSON object from a decoder into the ordered object.

func (*Object[V]) Values

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

Values returns all values in the ordered object.

type OrderedMarshaler added in v0.1.2

type OrderedMarshaler interface {
	MarshalJSONTo(enc *jsontext.Encoder) error
}

OrderedMarshaler is an interface for objects that can marshal themselves to JSON while preserving key order.

Directories

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

Jump to

Keyboard shortcuts

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