atom

package module
v0.0.1 Latest Latest
Warning

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

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

README

atom

CI Status codecov Go Report Card CodeQL Go Reference License Go Version Release

Type-segregated atomic value decomposition for Go — break structs into typed atoms, reconstruct them later.

The Problem

Storing complex structs often means choosing between:

  • Full serialization — JSON/protobuf blobs that can't be queried field-by-field
  • ORM mapping — heavy frameworks with reflection overhead on every operation
  • Manual decomposition — tedious, error-prone code for each type

The Solution

Atom provides a clean abstraction for decomposing structs into typed atomic values:

type User struct {
    ID        string
    Name      string
    Age       int64
    Balance   float64
    Active    bool
    CreatedAt time.Time
}

atomizer := atom.New[User](atomizeUser, deatomizeUser)

// Decompose to atoms
atoms, _ := atomizer.Atomize(&user)
// atoms.Strings["Name"] = "Alice"
// atoms.Ints["Age"] = 30
// atoms.Floats["Balance"] = 100.50

// Reconstruct from atoms
user, _ := atomizer.Deatomize(atoms)

You provide the transformation functions. Atom handles:

  • Type segregation — strings, ints, floats, bools, times in separate maps
  • Field metadata — automatic introspection via sentinel
  • Validation — runs before atomization
  • Binary encoding — utilities for storage-ready byte conversion

Features

  • Storage-agnostic — bring your own persistence layer
  • Type-safe genericsAtomizer[T] catches errors at compile time
  • Sentinel integration — automatic field discovery and metadata
  • Binary encoding — big-endian ints (sortable), RFC3339Nano times
  • Validation hooks — implement Validator interface for pre-atomization checks

Install

go get github.com/zoobzio/atom@latest

Requires Go 1.23+.

Quick Start

package main

import (
    "fmt"
    "time"

    "github.com/zoobzio/atom"
)

type Order struct {
    ID     string  `atom:"id"`
    Total  float64
    Status string
}

func (o Order) Validate() error {
    if o.ID == "" {
        return fmt.Errorf("ID required")
    }
    return nil
}

func atomizeOrder(o *Order) atom.Atoms {
    atoms := atom.NewAtoms(o.ID)
    atoms.Floats["Total"] = o.Total
    atoms.Strings["Status"] = o.Status
    return *atoms
}

func deatomizeOrder(atoms atom.Atoms) (*Order, error) {
    return &Order{
        ID:     atoms.ID,
        Total:  atoms.Floats["Total"],
        Status: atoms.Strings["Status"],
    }, nil
}

func main() {
    atomizer := atom.New[Order](atomizeOrder, deatomizeOrder)

    order := &Order{ID: "order-123", Total: 99.99, Status: "pending"}

    // Decompose
    atoms, _ := atomizer.Atomize(order)
    fmt.Printf("ID: %s, Total: %.2f\n", atoms.ID, atoms.Floats["Total"])

    // Reconstruct
    restored, _ := atomizer.Deatomize(atoms)
    fmt.Printf("Restored: %+v\n", restored)
}

API Reference

Core Types
Type Purpose
Atomizer[T] Generic atomizer for type T
Atoms Container for decomposed atomic values
Atomize[T] Function type: *TAtoms
Deatomize[T] Function type: Atoms(*T, error)
Validator Interface with Validate() error
Atomizer Methods
Method Purpose
New[T](atomize, deatomize) Create an atomizer for type T
Atomize(obj) Decompose object to atoms (validates first)
Deatomize(atoms) Reconstruct object from atoms
Metadata() Get sentinel metadata for type T
Fields() Get all field descriptors
FieldsIn(table) Get field names for a table type
TableFor(field) Get table type for a field name
Table Types
TableType Go Types
TableStrings string
TableInts int, int8...int64, uint...uint64
TableFloats float32, float64
TableBools bool
TableTimes time.Time
Encoding Utilities
Function Format
encodeString / decodeString UTF-8 bytes
encodeInt64 / decodeInt64 Big-endian (sortable)
encodeFloat64 / decodeFloat64 IEEE 754 binary
encodeBool / decodeBool Single byte (0/1)
encodeTime / decodeTime RFC3339Nano string

Design

Atom is intentionally minimal. It provides:

  1. Decomposition abstraction — the Atoms container and transformation types
  2. Field introspection — via sentinel integration
  3. Encoding utilities — for storage-ready byte conversion

It does not provide:

  • Storage backends
  • Query interfaces
  • Caching layers

This design allows atom to be used within storage libraries (like grub) without circular dependencies.

Contributing

See CONTRIBUTING.md for guidelines.

License

MIT License — see LICENSE for details.

Documentation

Overview

Package atom provides type-segregated atomic value storage.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDecode indicates decoding failed.
	ErrDecode = errors.New("atom: decoding failed")

	// ErrMissingID indicates the Atoms.ID field is empty.
	ErrMissingID = errors.New("atom: missing ID in atoms")
)

Functions

This section is empty.

Types

type Atomize

type Atomize[T any] func(*T) Atoms

Atomize converts a value to its atomic representation.

type Atomizer

type Atomizer[T Validator] struct {
	// contains filtered or unexported fields
}

Atomizer provides typed bidirectional resolution for any type T. T must implement Validator to ensure data integrity before storage.

func New

func New[T Validator](atomize Atomize[T], deatomize Deatomize[T]) *Atomizer[T]

New creates an Atomizer for type T using the provided callbacks. Inspects T at construction time to build field metadata.

func (*Atomizer[T]) Atomize

func (a *Atomizer[T]) Atomize(obj *T) (Atoms, error)

Atomize converts an object to its atomic representation.

func (*Atomizer[T]) Deatomize

func (a *Atomizer[T]) Deatomize(atoms Atoms) (*T, error)

Deatomize reconstructs an object from its atomic representation.

func (*Atomizer[T]) Fields

func (a *Atomizer[T]) Fields() []FieldDescriptor

Fields returns all field descriptors.

func (*Atomizer[T]) FieldsIn

func (a *Atomizer[T]) FieldsIn(table TableType) []string

FieldsIn returns field names stored in the given table.

func (*Atomizer[T]) Metadata

func (a *Atomizer[T]) Metadata() sentinel.Metadata

Metadata returns the sentinel.Metadata for type T.

func (*Atomizer[T]) TableFor

func (a *Atomizer[T]) TableFor(field string) (TableType, bool)

TableFor returns the table type for a field name.

type Atoms

type Atoms struct {
	ID      string
	Strings map[string]string
	Ints    map[string]int64
	Floats  map[string]float64
	Bools   map[string]bool
	Times   map[string]time.Time
}

Atoms holds decomposed atomic values by type.

func NewAtoms

func NewAtoms(id string) *Atoms

NewAtoms creates an Atoms with initialized maps.

type Deatomize

type Deatomize[T any] func(Atoms) (*T, error)

Deatomize reconstructs a value from its atomic representation.

type FieldDescriptor

type FieldDescriptor struct {
	Name  string
	Table TableType
}

FieldDescriptor maps a field name to its storage table.

type TableType

type TableType string

TableType identifies the segregated storage table for atomic values.

const (
	TableStrings TableType = "strings"
	TableInts    TableType = "ints"
	TableFloats  TableType = "floats"
	TableBools   TableType = "bools"
	TableTimes   TableType = "times"
)

Table type constants for type-segregated storage.

func AllTables

func AllTables() []TableType

AllTables returns all table types in canonical order.

func (TableType) Prefix

func (t TableType) Prefix() string

Prefix returns the storage key prefix for this table type.

type Validator

type Validator interface {
	Validate() error
}

Validator provides validation before atomization.

Jump to

Keyboard shortcuts

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