serialization

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package serialization provides Arc JSON naming, null omission and presence-aware binding. It does not perform HTTP body limiting or application validation.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrInvalidEnumValue = errors.New("invalid Int32 enum JSON value")

ErrInvalidEnumValue identifies an input rejected by Int32Enum.ParseJSON. Errors do not include the supplied payload.

Functions

func CamelCase

func CamelCase(name string) string

CamelCase uses Arc's acronym-friendly policy: ID and URLValue remain unchanged; ordinary PascalCase names become camelCase. Explicit json tags take precedence.

func Marshal

func Marshal(value any) ([]byte, error)

Marshal encodes Arc camelCase structs, retaining zeros and omitting nil object properties. Nil elements in collections remain null. Custom JSON and text marshaler implementations own their wire format. String-key maps retain null entries. Embedded structs promote exported fields using encoding/json precedence. Non-string map keys need a custom codec. Framework nesting is limited to 64 levels; cycles fail rather than recursing indefinitely. No input is retained.

func RegisterDerivedTypes

func RegisterDerivedTypes(declarations ...DerivedDeclaration) error

RegisterDerivedTypes installs process-wide wire declarations, like the frontend derived-type registry. Call during composition, before handling requests. The complete batch is validated before publication. Exact repeated declarations are idempotent; conflicting IDs/types fail without changing the registry. Calls and subsequent serialization are concurrency-safe. No codecs are executed.

func Unmarshal

func Unmarshal(data []byte, target any) error

Unmarshal binds one complete JSON value into a non-nil pointer. It starts with a fresh value and only replaces the target after success. Struct names are matched exactly, unknown members ignored, and exact duplicate declared keys rejected. Optional preserves missing/null/zero. Non-nullable scalars reject null. Custom JSON and text unmarshaler implementations own their binding rules. Untyped numbers become json.Number to preserve integer precision. Inputs are not retained.

func ValidateType

func ValidateType(t reflect.Type) error

ValidateType prepares Arc's field plans and rejects invalid concept declarations in a model, its pointers, collections and exported JSON fields. Call it when registering a model to fail before serving requests. Marshal and Unmarshal also call it before using a type. Errors preserve Fundamentals.Go's ErrInvalidConcept and *concepts.TypeError for errors.Is/As. Calls are concurrency-safe and cached per exact type, including errors. No application values or codecs are executed. Custom non-concept codecs are opaque; interfaces are checked when their concrete values are encoded. This does not validate codec output or domain invariants.

Types

type DerivedDeclaration

type DerivedDeclaration struct {
	// Default selects the concrete base representation when no discriminator is supplied.
	// Its ID must be empty; explicit unknown IDs still fail closed.
	Default bool
	ID      string
	Base    reflect.Type
	Type    reflect.Type
}

DerivedDeclaration explicitly associates a concrete struct (or its pointer) with a named interface wire contract and a canonical UUID discriminator. Go embedding alone is not inheritance. Codecs on derived structs are unsupported.

type DuplicateMemberError

type DuplicateMemberError struct {
	// Member is the declared wire name, not the supplied value.
	Member string
}

DuplicateMemberError identifies ambiguous supplied names for one declared field. Use errors.As to inspect it. Unknown properties are ignored, including duplicates.

func (*DuplicateMemberError) Error

func (e *DuplicateMemberError) Error() string

Error describes the rejected member without exposing its value.

type Int32Enum

type Int32Enum[T ~int32] struct {
	// contains filtered or unexported fields
}

Int32Enum parses the explicit Int32 enum profile used by Arc 22.48.2 with Fundamentals 7.19.6. Construct it with NewInt32Enum. It is immutable and safe for concurrent use; a nil receiver or zero value rejects all input.

Numeric JSON accepts only declared values. Case-insensitive original names, comma-separated names (bitwise OR, even without Flags), and decimal strings are accepted. Decimal strings may contain ANY Int32, including undeclared values. Ordinary numeric JSON writes likewise retain the full Int32 domain: this profile deliberately does not promise that every write can be read back. Later Fundamentals versions have different numeric flags admission.

Use ParseJSON from a named Int32 type's UnmarshalJSON method. Its normal JSON encoding already writes numbers; no global registration or marshal hook is needed. Pointers and Optional own null/presence outside this scalar parser. This does not change ordinary Go integer decoding or add generator metadata. Other backing widths and non-ASCII parse-name declarations are unsupported. TypeScript export renames must not be supplied as original parse names.

Example
package main

import (
	"fmt"

	"github.com/cratis/arc.go/serialization"
)

type state int32

var stateCodec, stateCodecError = serialization.NewInt32Enum(map[string]state{"None": 0, "Read": 1, "Write": 4, "Alias": 4})

func (s *state) UnmarshalJSON(data []byte) error {
	if stateCodecError != nil {
		return stateCodecError
	}
	value, err := stateCodec.ParseJSON(data)
	if err != nil {
		return err
	}
	*s = value
	return nil
}

func main() {
	var input struct{ State state }
	if err := serialization.Unmarshal([]byte(`{"state":"Read, Write"}`), &input); err != nil {
		fmt.Println(err)
		return
	}
	wire, err := serialization.Marshal(input)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(wire))
}
Output:
{"state":5}

func NewInt32Enum

func NewInt32Enum[T ~int32](members map[string]T) (*Int32Enum[T], error)

NewInt32Enum copies original parse names and their values. Names must be nonempty ASCII identifiers and unique ignoring ASCII case; multiple names may have the same value. Nil/empty declarations are invalid. Rejecting ambiguous case-only names is a deliberate Go admission restriction, not a CLR rule. The caller may subsequently change the input map without affecting the parser.

func (*Int32Enum[T]) ParseJSON

func (e *Int32Enum[T]) ParseJSON(data []byte) (T, error)

ParseJSON reads one complete scalar JSON value without retaining input. On failure it returns zero and ErrInvalidEnumValue, never a partially parsed OR combination. Null is rejected; use a pointer/Optional for nullable values.

type Optional

type Optional[T any] struct {
	// contains filtered or unexported fields
}

Optional distinguishes missing, explicit null and a supplied value (even zero). The zero value is missing. Use Marshal to omit missing struct properties; encoding/json alone writes missing values as null. Values are borrowed, not cloned.

func Null

func Null[T any]() Optional[T]

Null represents an explicit JSON null.

func Some

func Some[T any](value T) Optional[T]

Some represents a supplied value. A nil value still marshals as JSON null.

func (Optional[T]) IsNull

func (o Optional[T]) IsNull() bool

IsNull reports whether the property was explicitly null.

func (Optional[T]) IsPresent

func (o Optional[T]) IsPresent() bool

IsPresent reports whether the property was supplied, including null.

func (Optional[T]) IsZero

func (o Optional[T]) IsZero() bool

IsZero reports missing presence, for encoding/json's omitzero support.

func (Optional[T]) MarshalJSON

func (o Optional[T]) MarshalJSON() ([]byte, error)

MarshalJSON emits null for missing/null, otherwise the Arc-encoded value.

func (*Optional[T]) UnmarshalJSON

func (o *Optional[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON records explicit null, leaving o unchanged if binding fails.

func (Optional[T]) Value

func (o Optional[T]) Value() (T, bool)

Value returns the supplied non-null value; false means missing or explicit null.

Jump to

Keyboard shortcuts

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