marshaller

package
v1.7.3 Latest Latest
Warning

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

Go to latest
Published: Sep 19, 2025 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClearGlobalFieldCache added in v1.0.0

func ClearGlobalFieldCache()

ClearGlobalFieldCache clears the global field cache. This is useful for testing or memory management when the cache is no longer needed.

func CreateInstance added in v0.2.2

func CreateInstance(typ reflect.Type) reflect.Value

CreateInstance creates a new instance using registered factory or falls back to reflection

func DecodeNode added in v0.2.2

func DecodeNode(ctx context.Context, parentName string, node *yaml.Node, out any) ([]error, error)

DecodeNode attempts to decode a YAML node into the provided output value. It differentiates between type mismatch errors (returned as validation errors) and YAML syntax errors (returned as standard errors).

Returns:

  • []error: validation errors for type mismatches
  • error: syntax errors or other decode failures

func IsRegistered added in v0.2.2

func IsRegistered(typ reflect.Type) bool

IsRegistered checks if a type has a registered factory

func Marshal added in v0.2.2

func Marshal[T any](ctx context.Context, model Marshallable[T], w io.Writer) error

Marshal will marshal the provided high-level model to the provided io.Writer. It syncs any changes from the high-level model to the core model, then marshals the core model.

func Populate added in v0.2.1

func Populate(source any, target any) error

func PopulateModel

func PopulateModel(source any, target any) error

func PopulateWithParent added in v1.4.0

func PopulateWithParent(source any, target any, parent any) error

func RegisterType added in v0.2.2

func RegisterType[T any](factory func() *T)

RegisterType registers a factory function for a specific type This should be called in init() functions of packages that define models

func Sync added in v1.0.0

func Sync[T any](ctx context.Context, model Marshallable[T]) (*yaml.Node, error)

Sync will sync the high-level model to the core model. This is useful when creating or mutating a high-level model and wanting access to the yaml nodes that back it.

func SyncValue

func SyncValue(ctx context.Context, source any, target any, valueNode *yaml.Node, skipCustomSyncer bool) (node *yaml.Node, err error)

SyncValue syncs changes from source to target and returns the updated YAML node. For proper YAML node styling (quoted strings, etc.), ensure the context contains the config via yml.ContextWithConfig(ctx, config) before calling this function.

func Unmarshal

func Unmarshal[T any](ctx context.Context, in io.Reader, out CoreAccessor[T]) ([]error, error)

Unmarshal will unmarshal the provided document into the specified model.

func UnmarshalCore added in v0.2.2

func UnmarshalCore(ctx context.Context, parentName string, node *yaml.Node, out any) ([]error, error)

func UnmarshalExtension added in v0.2.1

func UnmarshalExtension(keyNode *yaml.Node, valueNode *yaml.Node, extensionsField reflect.Value) error

func UnmarshalKeyValuePair added in v0.2.1

func UnmarshalKeyValuePair(ctx context.Context, parentName string, keyNode, valueNode *yaml.Node, outValue any) ([]error, error)

func UnmarshalModel added in v0.2.1

func UnmarshalModel(ctx context.Context, node *yaml.Node, structPtr any) ([]error, error)

func UnmarshalNode added in v1.0.0

func UnmarshalNode[T any](ctx context.Context, parentName string, node *yaml.Node, out CoreAccessor[T]) ([]error, error)

UnmarshalNode will unmarshal the provided node into the provided model. This method is useful for unmarshaling partial documents, for a full document use Unmarshal as it will retain the full document structure.

Types

type CachedFieldInfo added in v1.0.0

type CachedFieldInfo struct {
	Name         string
	Index        int
	Required     bool
	Tag          string
	IsExported   bool
	IsExtensions bool
}

CachedFieldInfo contains the cached information about a struct field

type CachedFieldMaps added in v1.0.0

type CachedFieldMaps struct {
	Fields         map[string]CachedFieldInfo
	ExtensionIndex int             // Index of extensions field, -1 if none
	HasExtensions  bool            // Whether there's an extensions field
	FieldIndexes   map[string]int  // tag -> field index mapping
	RequiredFields map[string]bool // tag -> required status for quick lookup
}

CachedFieldMaps contains the complete cached field processing result

type CoreAccessor added in v0.2.1

type CoreAccessor[T any] interface {
	GetCore() *T
	SetCore(core *T)
}

CoreAccessor provides type-safe access to the core field in models

type CoreModel added in v0.2.1

type CoreModel struct {
	RootNode  *yaml.Node  // RootNode is the node that was unmarshaled into this model
	Valid     bool        // Valid indicates whether the model passed validation, ie all its required fields were present and ValidYaml is true
	ValidYaml bool        // ValidYaml indicates whether the model's underlying YAML representation is valid, for example a mapping node was received for a model
	Config    *yml.Config // Generally only set on the top-level model that was unmarshaled
}

func (*CoreModel) DetermineValidity added in v0.2.2

func (c *CoreModel) DetermineValidity(errs []error)

func (*CoreModel) GetConfig added in v0.2.2

func (c *CoreModel) GetConfig() *yml.Config

func (*CoreModel) GetJSONPath added in v1.0.0

func (c *CoreModel) GetJSONPath(topLevelRootNode *yaml.Node) string

GetJSONPath returns the JSONPath expression from the topLevelRootNode to this CoreModel's RootNode. Returns an empty string if the node is not found or if either node is nil. The returned path follows JSONPath format (e.g., "$.paths['/some/path'].get").

func (*CoreModel) GetJSONPointer added in v1.0.0

func (c *CoreModel) GetJSONPointer(topLevelRootNode *yaml.Node) string

GetJSONPointer returns the JSON pointer path from the topLevelRootNode to this CoreModel's RootNode. Returns an empty string if the node is not found or if either node is nil. The returned pointer follows RFC6901 format (e.g., "/path/to/node").

func (CoreModel) GetRootNode added in v0.2.1

func (c CoreModel) GetRootNode() *yaml.Node

func (CoreModel) GetRootNodeLine added in v1.0.0

func (c CoreModel) GetRootNodeLine() int

func (CoreModel) GetValid added in v0.2.1

func (c CoreModel) GetValid() bool

func (CoreModel) GetValidYaml added in v0.2.2

func (c CoreModel) GetValidYaml() bool

func (*CoreModel) Marshal added in v0.2.2

func (c *CoreModel) Marshal(ctx context.Context, w io.Writer) error

Marshal will marshal the core model to the provided io.Writer. This method handles both YAML and JSON output based on the context configuration.

func (*CoreModel) SetConfig added in v0.2.2

func (c *CoreModel) SetConfig(config *yml.Config)

func (*CoreModel) SetRootNode added in v0.2.1

func (c *CoreModel) SetRootNode(rootNode *yaml.Node)

func (*CoreModel) SetValid added in v0.2.1

func (c *CoreModel) SetValid(valid, validYaml bool)

type CoreModeler added in v0.2.1

type CoreModeler interface {
	GetRootNode() *yaml.Node
	SetRootNode(rootNode *yaml.Node)
	GetValid() bool
	GetValidYaml() bool
	SetValid(valid, validYaml bool)
	DetermineValidity(errs []error)
	SetConfig(config *yml.Config)
	GetConfig() *yml.Config
	Marshal(ctx context.Context, w io.Writer) error
}

type CoreSetter added in v0.2.1

type CoreSetter interface {
	SetCoreAny(core any)
}

CoreSetter provides runtime access to set the core field

type Extension added in v0.1.0

type Extension = *yaml.Node

type ExtensionCoreMap

type ExtensionCoreMap interface {
	Get(string) (Node[Extension], bool)
	Set(string, Node[Extension])
	Delete(string)
	All() iter.Seq2[string, Node[Extension]]
	Init()
}

type ExtensionMap

type ExtensionMap interface {
	Set(string, Extension)
	Init()
	SetCore(any)
}

type ExtensionSourceIterator

type ExtensionSourceIterator interface {
	All() iter.Seq2[string, Extension]
}

type FieldCacheStats added in v1.0.0

type FieldCacheStats struct {
	Size int64
}

FieldCacheStats returns basic statistics about the field cache

func GetFieldCacheStats added in v1.0.0

func GetFieldCacheStats() FieldCacheStats

GetFieldCacheStats returns statistics about the global field cache

type MapGetter added in v0.2.2

type MapGetter interface {
	AllUntyped() iter.Seq2[any, any]
}

MapGetter interface for syncing operations

type Marshallable added in v0.2.2

type Marshallable[T any] interface {
	GetCore() *T
	GetRootNode() *yaml.Node
}

Marshallable represents a high-level model that can be marshaled

type Model added in v0.2.1

type Model[T any] struct {
	// Valid indicates whether this model passed validation.
	Valid bool
	// contains filtered or unexported fields
}

Model is a generic model that can be used to validate and marshal/unmarshal a model.

func (*Model[T]) GetCachedReferenceDocument added in v1.0.0

func (m *Model[T]) GetCachedReferenceDocument(key string) ([]byte, bool)

func (*Model[T]) GetCachedReferencedObject added in v1.0.0

func (m *Model[T]) GetCachedReferencedObject(key string) (any, bool)

func (*Model[T]) GetCore added in v0.2.1

func (m *Model[T]) GetCore() *T

GetCore will return the low level representation of the model. Useful for accessing line and column numbers for various nodes in the backing yaml/json document.

func (*Model[T]) GetCoreAny added in v0.2.2

func (m *Model[T]) GetCoreAny() any

GetCoreAny will return the low level representation of the model untyped. Useful for using with interfaces and reflection.

func (*Model[T]) GetPropertyLine added in v1.0.0

func (m *Model[T]) GetPropertyLine(prop string) int

func (*Model[T]) GetRootNode added in v0.2.1

func (m *Model[T]) GetRootNode() *yaml.Node

GetRootNode implements RootNodeAccessor interface by delegating to the core model.

This method provides access to the unique YAML node that was originally parsed for this model instance. The RootNode serves as a stable identity for the model that persists across array reorderings and other operations.

The method works by checking if the core model implements CoreModeler interface, which provides access to the RootNode. If the core doesn't implement CoreModeler, this returns nil, which causes the sync process to fall back to index-based matching.

This identity-based matching is crucial for preserving field ordering when high-level arrays are reordered, as it ensures each high-level model syncs with its correct corresponding core model rather than being matched by array position.

func (*Model[T]) GetRootNodeColumn added in v1.0.0

func (m *Model[T]) GetRootNodeColumn() int

func (*Model[T]) GetRootNodeLine added in v1.0.0

func (m *Model[T]) GetRootNodeLine() int

func (*Model[T]) InitCache added in v1.0.0

func (m *Model[T]) InitCache()

func (*Model[T]) SetCore added in v0.2.1

func (m *Model[T]) SetCore(core *T)

SetCore implements CoreAccessor interface

func (*Model[T]) SetCoreAny added in v1.0.0

func (m *Model[T]) SetCoreAny(core any)

SetCoreAny implements CoreSetter interface

func (*Model[T]) StoreReferenceDocumentInCache added in v1.0.0

func (m *Model[T]) StoreReferenceDocumentInCache(key string, doc []byte)

func (*Model[T]) StoreReferencedObjectInCache added in v1.0.0

func (m *Model[T]) StoreReferencedObjectInCache(key string, obj any)

type ModelWithCore added in v0.2.2

type ModelWithCore interface {
	GetCore() any
	GetRootNode() *yaml.Node
}

ModelWithCore represents a high-level model that has an embedded Model[T]

type Node

type Node[V any] struct {
	Key       string
	KeyNode   *yaml.Node
	Value     V
	ValueNode *yaml.Node
	Present   bool
}

func (Node[V]) GetKeyNode added in v1.0.0

func (n Node[V]) GetKeyNode() *yaml.Node

func (Node[V]) GetKeyNodeOrRoot

func (n Node[V]) GetKeyNodeOrRoot(rootNode *yaml.Node) *yaml.Node

func (Node[V]) GetKeyNodeOrRootLine added in v1.0.0

func (n Node[V]) GetKeyNodeOrRootLine(rootNode *yaml.Node) int

func (Node[V]) GetMapKeyNodeOrRoot

func (n Node[V]) GetMapKeyNodeOrRoot(key string, rootNode *yaml.Node) *yaml.Node

Will return the key node for the map key, or the map root node or the provided root node if the node is not present

func (Node[V]) GetMapKeyNodeOrRootLine added in v1.0.0

func (n Node[V]) GetMapKeyNodeOrRootLine(key string, rootNode *yaml.Node) int

func (Node[V]) GetMapValueNodeOrRoot

func (n Node[V]) GetMapValueNodeOrRoot(key string, rootNode *yaml.Node) *yaml.Node

Will return the value node for the map key, or the map root node or the provided root node if the node is not present

func (Node[V]) GetNavigableNode

func (n Node[V]) GetNavigableNode() (any, error)

func (Node[V]) GetSliceValueNodeOrRoot

func (n Node[V]) GetSliceValueNodeOrRoot(idx int, rootNode *yaml.Node) *yaml.Node

Will return the value node for the slice index, or the slice root node or the provided root node if the node is not present

func (Node[V]) GetValue

func (n Node[V]) GetValue() any

func (Node[V]) GetValueNode added in v0.2.2

func (n Node[V]) GetValueNode() *yaml.Node

func (Node[V]) GetValueNodeOrRoot

func (n Node[V]) GetValueNodeOrRoot(rootNode *yaml.Node) *yaml.Node

func (Node[V]) GetValueNodeOrRootLine added in v1.0.0

func (n Node[V]) GetValueNodeOrRootLine(rootNode *yaml.Node) int

func (Node[V]) GetValueType

func (n Node[V]) GetValueType() reflect.Type

func (*Node[V]) SetPresent

func (n *Node[V]) SetPresent(present bool)

func (*Node[V]) SyncValue

func (n *Node[V]) SyncValue(ctx context.Context, key string, value any) (*yaml.Node, *yaml.Node, error)

func (*Node[V]) Unmarshal

func (n *Node[V]) Unmarshal(ctx context.Context, parentName string, keyNode, valueNode *yaml.Node) ([]error, error)

type NodeAccessor

type NodeAccessor interface {
	GetValue() any
	GetValueType() reflect.Type
}

type NodeMutator

type NodeMutator interface {
	Unmarshal(ctx context.Context, parentName string, keyNode, valueNode *yaml.Node) ([]error, error)
	SetPresent(present bool)
	SyncValue(ctx context.Context, key string, value any) (*yaml.Node, *yaml.Node, error)
}

type ParentAwarePopulator added in v1.4.0

type ParentAwarePopulator interface {
	PopulateWithParent(source any, parent any) error
}

type Populator added in v0.2.1

type Populator interface {
	Populate(source any) error
}

type RootNodeAccessor added in v0.2.1

type RootNodeAccessor interface {
	GetRootNode() *yaml.Node
}

RootNodeAccessor provides access to the RootNode of a model's core for identity matching.

This interface solves a critical problem in array/map synchronization: when high-level arrays are reordered (e.g., moving workflows around in an Arazzo document), we need to match each high-level element with its corresponding core model to preserve field ordering and other state.

Without identity matching, the sync process would match elements by array position:

Source[0] -> Target[0], Source[1] -> Target[1], etc.

This causes problems when arrays are reordered because the wrong data gets synced to the wrong core objects, disrupting field ordering within individual elements.

With RootNode identity matching, we can match elements correctly:

Source[workflow-A] -> Target[core-for-workflow-A] (regardless of position)
Source[workflow-B] -> Target[core-for-workflow-B] (regardless of position)

The RootNode serves as a unique identity because it's the original YAML node that was parsed for each element, making it a stable identifier across reorderings.

type Syncer

type Syncer interface {
	SyncChanges(ctx context.Context, model any, valueNode *yaml.Node) (*yaml.Node, error)
}

type TypeFactory added in v0.2.2

type TypeFactory func() interface{}

TypeFactory represents a function that creates a new instance of a specific type

type Unmarshallable

type Unmarshallable interface {
	Unmarshal(ctx context.Context, parentName string, node *yaml.Node) ([]error, error)
}

Unmarshallable is an interface that can be implemented by types that can be unmarshalled from a YAML document. These types should handle the node being an alias node and resolve it to the actual value (retaining the original node where needed).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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