xtypes

package
v0.47.0 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: MPL-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package xtypes implements Dynamic Data for go-DDS (Milestone 9).

XTypes provides a runtime type system that allows distributed systems to evolve their data schemas without lock-step software updates. It is loosely aligned with the OMG DDS-XTypes 1.3 specification but simplified for idiomatic Go use.

Type System

A TypeDescriptor describes the structure of a named type: its fields, their primitive kinds, and optional/required status. A TypeIdentifier is a compact, content-addressed fingerprint of a descriptor derived from its stable canonical hash.

Dynamic Data

DynamicData is a schema-validated property map: values may only be set on fields declared in the associated TypeDescriptor. It serialises transparently to/from JSON.

Type Registry

TypeRegistry is a thread-safe store of TypeObject values (descriptor + identifier pairs). Participants use the registry to announce their types and to resolve types received from peers.

Compatibility Checking

CheckCompatibility implements the standard forward/backward type evolution rules:

  • New optional fields added to the writer are invisible but harmless to an older reader (forward compatibility).
  • New required fields expected by the reader but absent from the writer are incompatible (the reader would receive data it cannot interpret).
  • Renamed or type-changed fields are always incompatible.

Index

Constants

This section is empty.

Variables

View Source
var ErrTypeMismatch = errors.New("xtypes: type name already registered with different structure")

ErrTypeMismatch is returned by TypeRegistry.Register when a type with the same name but a different hash is already registered.

View Source
var GlobalTopicRegistry = NewTopicTypeRegistry()

GlobalTopicRegistry is the process-wide default TopicTypeRegistry. RegisterTopicCodec and LookupTopicType use this registry by default.

Functions

func RegisterTopicCodec added in v0.10.0

func RegisterTopicCodec[T any](r *TopicTypeRegistry, topic string, _ dds.Codec[T])

RegisterTopicCodec records that topic is encoded with codec[T]. The association between topic and the Go type T is stored in r (pass GlobalTopicRegistry for the process-wide default). The codec parameter is used only for type inference; it is not stored.

Types

type CompatibilityResult

type CompatibilityResult struct {
	Compatible bool   // true if reader and writer are compatible
	Reason     string // human-readable explanation when Compatible is false
}

CompatibilityResult describes whether a reader using one type descriptor can safely consume data produced by a writer using another.

func CheckCompatibility

func CheckCompatibility(writerTD, readerTD *TypeDescriptor) CompatibilityResult

CheckCompatibility reports whether a reader using readerTD can safely consume data written by a writer using writerTD.

The rules follow standard schema-evolution conventions:

  • Fields present in writer but absent in reader: always OK (forward compat).
  • Fields present in reader but absent in writer: OK only if Optional in reader.
  • Fields present in both: compatible only if they have the same Kind.

type DynamicData

type DynamicData struct {
	// contains filtered or unexported fields
}

DynamicData is a schema-validated property map. Values can only be set on fields declared in the associated TypeDescriptor.

DynamicData is NOT safe for concurrent use from multiple goroutines.

func NewDynamicData

func NewDynamicData(td *TypeDescriptor) *DynamicData

NewDynamicData creates a DynamicData backed by td.

func (*DynamicData) FromJSON

func (d *DynamicData) FromJSON(data []byte) error

FromJSON populates set fields from JSON. Only keys that match declared fields in the descriptor are stored; unknown keys are silently ignored (forward compatibility: old code reads new data).

func (*DynamicData) Get

func (d *DynamicData) Get(name string) (any, bool)

Get returns the value for name. The second return is false if the field has not been set (even if it is declared in the descriptor).

func (*DynamicData) Set

func (d *DynamicData) Set(name string, value any) error

Set sets the named field to value. Returns an error if name does not exist in the descriptor.

func (*DynamicData) ToJSON

func (d *DynamicData) ToJSON() ([]byte, error)

ToJSON serialises the set fields to JSON.

func (*DynamicData) TypeDescriptor

func (d *DynamicData) TypeDescriptor() *TypeDescriptor

TypeDescriptor returns the schema backing this DynamicData.

type FieldDescriptor

type FieldDescriptor struct {
	Name     string            // field name; must be unique within its parent
	Kind     TypeKind          // primitive kind
	Optional bool              // if false, the field is required
	Fields   []FieldDescriptor // for KindStruct: nested field descriptors
	Element  *FieldDescriptor  // for KindSeq: element type descriptor
}

FieldDescriptor describes one field within a TypeDescriptor.

type TopicCodecInfo added in v0.10.0

type TopicCodecInfo struct {
	// Topic is the DDS topic name.
	Topic string
	// TypeName is the Go reflect type name of the value type (e.g. "main.Reading").
	TypeName string
}

TopicCodecInfo describes the codec registration for a topic.

type TopicTypeRegistry added in v0.10.0

type TopicTypeRegistry struct {
	// contains filtered or unexported fields
}

TopicTypeRegistry maps topic names to Go value types for codec autodiscovery. It enables runtime inspection of which Go type is associated with each topic, without requiring a concrete Codec[T] value at lookup time.

Use RegisterTopicCodec to register a topic at startup, then LookupTopicType to retrieve the association anywhere in the program.

func NewTopicTypeRegistry added in v0.10.0

func NewTopicTypeRegistry() *TopicTypeRegistry

NewTopicTypeRegistry returns an empty TopicTypeRegistry.

func (*TopicTypeRegistry) All added in v0.10.0

func (r *TopicTypeRegistry) All() []TopicCodecInfo

All returns all registered topic→type associations, sorted by topic name.

func (*TopicTypeRegistry) Deregister added in v0.10.0

func (r *TopicTypeRegistry) Deregister(topic string)

Deregister removes the registration for topic. It is a no-op if topic is not registered.

func (*TopicTypeRegistry) LookupTopicType added in v0.10.0

func (r *TopicTypeRegistry) LookupTopicType(topic string) (string, bool)

LookupTopicType returns the Go type name registered for topic, or ("", false) if the topic has not been registered.

type TypeDescriptor

type TypeDescriptor struct {
	Name    string            // type name; must be unique within a [TypeRegistry]
	Version uint32            // schema version; 0 = unversioned
	Fields  []FieldDescriptor // top-level fields
}

TypeDescriptor describes a complete named schema.

type TypeIdentifier

type TypeIdentifier struct {
	Name string  // type name
	Hash [8]byte // first 8 bytes of SHA-256(canonical JSON representation)
}

TypeIdentifier is a compact, content-addressed reference to a TypeDescriptor. Two descriptors with identical structure produce the same TypeIdentifier regardless of the order in which they were created.

func Identify

func Identify(td *TypeDescriptor) TypeIdentifier

Identify computes the TypeIdentifier for td. The hash is derived from a sorted, canonical JSON encoding of the descriptor so that structurally identical types hash identically.

type TypeKind

type TypeKind uint8

TypeKind identifies the primitive kind of a FieldDescriptor.

const (
	KindBool    TypeKind = iota // bool
	KindInt32                   // int32
	KindInt64                   // int64
	KindFloat64                 // float64
	KindString                  // string
	KindBytes                   // []byte
	KindStruct                  // nested struct; Fields contains sub-descriptors
	KindSeq                     // variable-length sequence; Element points to element descriptor
)

func (TypeKind) String

func (k TypeKind) String() string

String returns a human-readable name for the kind.

type TypeObject

type TypeObject struct {
	ID         TypeIdentifier
	Descriptor TypeDescriptor
}

TypeObject pairs a TypeDescriptor with its content-addressed TypeIdentifier.

func NewTypeObject

func NewTypeObject(td TypeDescriptor) *TypeObject

NewTypeObject builds a TypeObject from td, computing the identifier automatically.

type TypeRegistry

type TypeRegistry struct {
	// contains filtered or unexported fields
}

TypeRegistry is a thread-safe store for TypeObject values.

func NewTypeRegistry

func NewTypeRegistry() *TypeRegistry

NewTypeRegistry creates an empty TypeRegistry.

func (*TypeRegistry) All

func (r *TypeRegistry) All() []*TypeObject

All returns a snapshot of all registered TypeObjects in name-sorted order.

func (*TypeRegistry) Lookup

func (r *TypeRegistry) Lookup(name string) (*TypeObject, bool)

Lookup returns the TypeObject registered under name, if any.

func (*TypeRegistry) Register

func (r *TypeRegistry) Register(to *TypeObject) error

Register stores to. Returns ErrTypeMismatch if a type with the same Name but a different hash is already registered. Registering the same TypeObject twice (same name and hash) is a no-op.

Jump to

Keyboard shortcuts

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