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 ¶
- Variables
- func CamelCase(name string) string
- func Marshal(value any) ([]byte, error)
- func RegisterDerivedTypes(declarations ...DerivedDeclaration) error
- func Unmarshal(data []byte, target any) error
- func ValidateType(t reflect.Type) error
- type DerivedDeclaration
- type DuplicateMemberError
- type Int32Enum
- type Optional
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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 ¶
CamelCase uses Arc's acronym-friendly policy: ID and URLValue remain unchanged; ordinary PascalCase names become camelCase. Explicit json tags take precedence.
func Marshal ¶
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 ¶
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 ¶
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 ¶
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.
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 (Optional[T]) MarshalJSON ¶
MarshalJSON emits null for missing/null, otherwise the Arc-encoded value.
func (*Optional[T]) UnmarshalJSON ¶
UnmarshalJSON records explicit null, leaving o unchanged if binding fails.