vamp

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2022 License: AGPL-3.0 Imports: 13 Imported by: 3

README

Vampire Data Serialization

Go Reference

Although it is not zero-copy, Vampire provides "direct access" to values, which means you can navigate down any path in a nested data structure without having to analyze too many other parts that come before the value you are looking for.

This property makes the format accessible – “perviam” in Latin. Just because “Vampire” sounds much cooler the format is called Vampire in the end. But vamp is the package name to Go for because its shorter and still associated with vampires.

What sense does this property make for a serialization format?

Message brokers, queuing systems, and other types of middleware often have to make decisions about the data they manage based on tiny pieces of that data. This is often solved by artificially and redundantly adding the desired information as out-of-band data to the normal payload data. Or one decodes the data to find the relevant parts within the payload. If one chooses the second approach, it is more efficient to have to decode only the relevant parts of the payload.

That was the driving idea for the design of Vampire.

Data Types

TYPE ::= BASIC_TYPE | BYTES_TYPE | ARRAY_TYPE | RECORD_TYPE | LIST_TYPE |
         UNION_TYPE | ANY_TYPE
SIZE ::= 'Size8' | 'Size16' | 'Size32'
  • Basic Types: bool; signed and unsigned integers with 8, 16, 32 and 64 bit; 32-bit and 64-bit float

    BASIC_TYPE ::= 'bool' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint8' |
                   'uint16' | 'uint32' | 'unit64' | 'float32' | 'float64'
    
  • Bytes Type: Byte strings with either 8-, 16- or 32-bit size limits (size in Byte)

    BYTES_TYPE ::= '"' SIZE '"'`
    
  • Array Types: Variable length array with 8-bit, 16-bit and 32-bit length limits. Each element has the same type. Length is part of the array value not the array type. The length of an array must be known before writing an array value.

    ARRAY_TYPE ::= '[' SIZE ' ' TYPE ']'
    
  • Record Types: Fixed number of fields where each field has it's own type. Field names are optional and are not part of record values.

    RECORD_TYPE ::= '{' [ FIELD { ' ' FIELD } ] '}'
    
    FIELD ::= [ FIELD_NAME ':' ] TYPE
    
  • List Types: Unbounded (theoretically) sequence of values of the same type. Final length does not need to be known before writing. A 8-, 16- or 32-bit length fields is provided. If the final length fits, it will be recorded in the list value.

    LIST_TYPE ::= '(' SIZE ' ' TYPE ')'
    
  • Union Types: A tagged union with a predefined set of alternative value types. Tags can have 8-, 16- or 32-bit size.

    UNION_TYPE ::= '<' SIZE ' ' TYPE { '|' TYPE } '>'
    
  • Any Type: Write any Vampire value along with its Vampire type.

    ANY_TYPE ::= 'any'
    

Performance

Using this Go data structure with Vampire type {Age:int8 Name:"Size8" Owners:[Size8 "Size8"] Male:bool}

type Animal struct {
	Age    int      `vamp:",size=8"`
	Name   string   `vamp:",size=8"`
	Owners []string `vamp:",size=8:8"`
	Male   bool
}

Animal{Age: 4, Name: "Candy", Owners: []string{"Mary", "Joe"}, Male:   true}
Format Encoded Bytes Write&Read-Time / Best
Vampire (8-bit offsets) 22
Vampire (16-bit offsets) 26 1
Vampire (32-bit offsets) 34
JSON (Go std. lib) 60 2.33
GOB 113 21.30
CBOR 40 1.12

Encoding Format

Documentation

Overview

Package vamp implements the Vampire binary data serialization format for Go.

While Vampire does not provide zero-copy characteristics it gives you "direct access" to values i.e., you can navigate any path down into nested structures without parsing too many other parts that come before the value you are looking for. This feature makes any value directly accessible – “perviam” in Latin. Just because “Vampire” sounds much cooler the format is called Vampire in the end. But vamp is the package name to Go for because its shorter and still associated with vampires.

Type Promotion

TODO: float32 → float64; sized ints; machine int/uint.

Date and Duration

By default as int64 <-> Unix time with millis.

Example
type Animal struct {
	Age    int      `vamp:"age,size=8"`
	Name   string   `vamp:",size=8"`
	Owners []string `vamp:",size=8:8"`
	Male   bool
}
// Use reflection to get the Vampire type
t, _ := TypeOf(Animal{})
// We use a 16-bit offset for the buffers
const BufferOffset = Size16
// Create write buffer with room for a Vampire header
wbuf, _ := NewWriteBuffer(t, BufferOffset, HeaderSize, nil)
// Write the header (incl. buffer's offset size) in front of data
copy(wbuf.AllBytes(), HeaderFor(BufferOffset).Bytes())
// Write a record of type t to the buffer. Value has to match type t.
t.Write(wbuf, Animal{
	Age:    4,
	Name:   "Lassie",
	Owners: []string{"Timmy", "Martin"},
	Male:   false,
})
// How may bytes did we write
fmt.Printf("With header: %d; Value data only: %d\n", len(wbuf.AllBytes()), len(wbuf.Bytes()))
// Now extract the complete buffer, incl. header
data := wbuf.AllBytes()
// Wrap data into a read buffer that expects the header at byte 0
// Reads buffer's offset size from header (We could also directly read from wbuf)
rbuf, _ := NewReadBuffer(t, data, false)
// We need the specific type – record – to select a field
rt := t.(*RecordType)
// Slice the read buffer to the 3rd field "Owners"
revert := rt.Field(rbuf, 2)
// Read the Owners into a string array
var owners []string
rt.FieldType(2).Read(rbuf, &owners)
// We want to unslice the buffer to return to the complete record
rbuf.Unslice(revert)
// Print what we got from the binary data
fmt.Println(owners)
Output:

With header: 35; Value data only: 31
[Timmy Martin]

Index

Examples

Constants

View Source
const (
	Version    = 0
	HeaderSize = len(Header{})
)

Variables

View Source
var (
	BoolType    boolType
	Int8Type    int8Type
	Int16Type   int16Type
	Int32Type   int32Type
	Int64Type   int64Type
	Uint8Type   uint8Type
	Uint16Type  uint16Type
	Uint32Type  uint32Type
	Uint64Type  uint64Type
	Float32Type float32Type
	Float64Type float64Type
)

Vampire Basic Types

Each <N>Type variable implements Type and represents a Vampire type that corresponds directly to a Go type <n> where <n> is <N> folded to lower case e.g., BoolType corresponds to Go's bool type.

Marshaler and Unmarshaler interfaces are not explicitly defined for basic types. To implement user defined (un-)marshaling to or from <N>Type a value has to implement methods that match the following convention:

The marshaler for writing <n> to <N>Type:

interface{ VampTo<N>() (<n>, error) }

The unmarshaler for reading <n> from <N>Type:

interface{ VampFrom<N>(<n>) error }
View Source
var AnyType anyType

Functions

func ResetTypeBuffer

func ResetTypeBuffer(buf *Buffer, off SizeRange, prefix int)

func WriteType

func WriteType(buf *Buffer, t Type) error

Types

type Alt

type Alt struct {
	S uint
	V any
}

func (Alt) VampUnionAlt

func (a Alt) VampUnionAlt() (uint, any)

type AnyMarshaler

type AnyMarshaler interface {
	VampAnyType() (Type, any)
}

type ArrayMarshaler

type ArrayMarshaler interface {
	VampArrayLen() uint
	VampArrayWriter(i uint) (any, error)
}

type ArrayType

type ArrayType struct {
	// contains filtered or unexported fields
}
Example
a := []string{"boo", "bar", "baz"}
t, _ := TypeOf(a)
fmt.Println(t)
buf, _ := NewWriteBuffer(t, Size16, 0, nil)
t.Write(buf, a)
var out []string
t.Read(&buf.ReadBuffer, &out)
fmt.Printf("%[1]T=%[1]v\n", out)
Output:

[Size32 "Size16"]
[]string=[boo bar baz]

func NewArrayType

func NewArrayType(length SizeRange, elem Type) (*ArrayType, error)

func NewOptionalType

func NewOptionalType(elem Type) *ArrayType

NewOptionalType returns an ArrayType with length of Size8 – the smallest sufficient size range. This is the recommended way to represent optional values.

Example
et, _ := NewBytesType(Size8)
ot := NewOptionalType(et)
buf, _ := NewWriteBuffer(ot, Size8, 0, nil)
ot.WriteOptOne(buf, "Hello, optional!")
var out string
ok, _ := ot.ReadOpt(&buf.ReadBuffer, &out)
fmt.Println(ok, out)
buf.Reset(ot, Size16, 0)
ot.WriteOptNone(buf)
out = "-"
ok, _ = ot.ReadOpt(&buf.ReadBuffer, &out)
fmt.Println(ok, out)
Output:

true Hello, optional!
false -

func (*ArrayType) DynNo

func (t *ArrayType) DynNo() uint

func (*ArrayType) Elem

func (t *ArrayType) Elem() Type

func (*ArrayType) Equals

func (a *ArrayType) Equals(t Type) bool

func (*ArrayType) FixSize

func (t *ArrayType) FixSize() uint

func (*ArrayType) Hash

func (a *ArrayType) Hash(h hash.Hash)

func (*ArrayType) Index

func (t *ArrayType) Index(buf *ReadBuffer, i uint) (revert uint)

func (*ArrayType) Len

func (t *ArrayType) Len(buf *ReadBuffer) uint

func (*ArrayType) LenRange

func (t *ArrayType) LenRange() SizeRange

func (*ArrayType) Read

func (t *ArrayType) Read(buf *ReadBuffer, into any) error

func (*ArrayType) ReadArray

func (t *ArrayType) ReadArray(buf *ReadBuffer, ls ArrayUnmarshaler) error

func (*ArrayType) ReadOpt

func (t *ArrayType) ReadOpt(buf *ReadBuffer, into any) (ok bool, err error)

func (*ArrayType) String

func (t *ArrayType) String() string

func (*ArrayType) VampRecordRead

func (t *ArrayType) VampRecordRead(rt *RecordType, buf *ReadBuffer) error

func (*ArrayType) VampRecordWrite

func (t *ArrayType) VampRecordWrite(rt *RecordType, buf *Buffer) error

func (*ArrayType) VampUnionAlt

func (t *ArrayType) VampUnionAlt() (uint, any)

func (*ArrayType) Write

func (t *ArrayType) Write(buf *Buffer, ls any) (err error)

func (*ArrayType) WriteArray

func (t *ArrayType) WriteArray(buf *Buffer, ls ArrayMarshaler) error

func (*ArrayType) WriteOptNone

func (t *ArrayType) WriteOptNone(buf *Buffer) error

func (*ArrayType) WriteOptOne

func (t *ArrayType) WriteOptOne(buf *Buffer, value any) error

type ArrayUnmarshaler

type ArrayUnmarshaler interface {
	VampArrayResize(l uint) error
	VampArrayReader(i uint) (any, error)
	VampArrayFinish() error
}

type Buffer

type Buffer struct {
	ReadBuffer
}

func NewTypeWriteBuffer

func NewTypeWriteBuffer(off SizeRange, at int, buf []byte) (*Buffer, error)

func NewWriteBuffer

func NewWriteBuffer(t Type, off SizeRange, at int, buf []byte) (*Buffer, error)

func (*Buffer) Reset

func (b *Buffer) Reset(t Type, off SizeRange, prefix int) error

type BytesMode

type BytesMode uint8
const (
	BytesUTF8 BytesMode = iota
	BytesRaw
	BytesString
)

type BytesType

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

func NewBytesType

func NewBytesType(size SizeRange) (BytesType, error)

func NewBytesTypeMode

func NewBytesTypeMode(size SizeRange, mode BytesMode) (BytesType, error)

func (BytesType) DynNo

func (t BytesType) DynNo() uint

func (BytesType) Equals

func (s BytesType) Equals(t Type) bool

func (BytesType) FixSize

func (t BytesType) FixSize() uint

func (BytesType) Hash

func (s BytesType) Hash(h hash.Hash)

func (BytesType) LenRange

func (t BytesType) LenRange() SizeRange

func (BytesType) Read

func (t BytesType) Read(buf *ReadBuffer, into any) (err error)

User Defined Unmarshaling

Unmarshaling from byte array:

interface{ VampFromBytes([]byte) error } // must copy its argument

Unmarshaling from string:

interface{ VampFromString(string) error }

func (BytesType) ReadBytes

func (t BytesType) ReadBytes(buf *ReadBuffer) []byte

func (BytesType) ReadString

func (t BytesType) ReadString(buf *ReadBuffer) string

func (BytesType) String

func (t BytesType) String() string

func (*BytesType) VampFromUint8

func (t *BytesType) VampFromUint8(v uint8) error

func (BytesType) VampToUint8

func (t BytesType) VampToUint8() (uint8, error)

func (BytesType) VampUnionAlt

func (t BytesType) VampUnionAlt() (uint, any)

func (BytesType) Write

func (t BytesType) Write(buf *Buffer, value any) error

User Defined Marshaling

Marshaling to byte array:

interface{ VampToBytes() ([]byte, error) }

Marshaling to string:

interface{ VampToString() (string, error) }

func (BytesType) WriteBytes

func (t BytesType) WriteBytes(buf *Buffer, data []byte) error

func (BytesType) WriteString

func (t BytesType) WriteString(buf *Buffer, s string) error
type Header [4]byte

Header is the VMP header that can be written to buffers to mark the data to be Vampire encoded and to provide the offsetSize used for the data.

The VMP header is "VMPn" where n == offsetSize.Size().

Example
fmt.Println(HeaderFor(Size16))
Output:

Vampire-v0+16bit

func HeaderFor

func HeaderFor(s SizeRange) Header

HeaderFor clapms s to valid range

func ParseHeader

func ParseHeader(mem []byte) (h Header, pos int)

func (Header) Bytes

func (h Header) Bytes() []byte

func (Header) SizeRange

func (h Header) SizeRange() SizeRange

func (Header) String

func (h Header) String() string

func (Header) Version

func (h Header) Version() int

type ListIterator

type ListIterator interface {
	VampListNext() bool
	VampListGet() any
}

type ListMarshaler

type ListMarshaler interface {
	VampListIter() ListIterator
}

type ListType

type ListType struct {
	// contains filtered or unexported fields
}
Example
a := []string{"boo", "bar", "baz"}
t, _ := NewListType(Size32, catch.MustRet(NewBytesType(Size16)))
fmt.Println(t)
buf, _ := NewWriteBuffer(t, Size16, 0, nil)
t.Write(buf, a)
var out any
t.Read(&buf.ReadBuffer, &out)
fmt.Printf("%[1]T=%[1]v\n", out)
Output:

(Size32 "Size16")
[]interface {}=[boo bar baz]

func NewListType

func NewListType(length SizeRange, elem Type) (*ListType, error)

func (*ListType) DynNo

func (t *ListType) DynNo() uint

func (*ListType) Elem

func (t *ListType) Elem() Type

func (*ListType) Equals

func (l *ListType) Equals(t Type) bool

func (*ListType) FixSize

func (t *ListType) FixSize() uint

func (*ListType) Hash

func (a *ListType) Hash(h hash.Hash)

func (*ListType) LenRange

func (t *ListType) LenRange() SizeRange

func (*ListType) ListLen

func (t *ListType) ListLen(buf *ReadBuffer) (len uint, ok bool)

func (*ListType) Next

func (t *ListType) Next(buf *ReadBuffer) (revert uint, ok bool)

TODO Test ListType.Next()

func (*ListType) Read

func (t *ListType) Read(buf *ReadBuffer, into any) error

func (*ListType) ReadList

func (t *ListType) ReadList(buf *ReadBuffer, into ListUnmarshaler) error

func (*ListType) String

func (t *ListType) String() string

func (*ListType) VampRecordRead

func (t *ListType) VampRecordRead(rt *RecordType, buf *ReadBuffer) error

func (*ListType) VampRecordWrite

func (t *ListType) VampRecordWrite(rt *RecordType, buf *Buffer) error

func (*ListType) VampUnionAlt

func (t *ListType) VampUnionAlt() (uint, any)

func (*ListType) Write

func (t *ListType) Write(buf *Buffer, val any) error

func (*ListType) WriteList

func (t *ListType) WriteList(buf *Buffer, ls ListMarshaler) error

type ListUnmarshaler

type ListUnmarshaler interface {
	VampListReader() (any, error)
	VampListAppend(any) error
}

type PathElement added in v0.2.0

type PathElement struct {
	T   Type
	Idx uint
}

type PathError added in v0.2.0

type PathError struct {
	// contains filtered or unexported fields
}
Example
rt, _ := NewRecordType(
	catch.MustRet(NewBytesType(Size16)),
	Float64Type,
	BoolType,
)
buf, _ := NewWriteBuffer(rt, Size16, 0, nil)
err := rt.WriteFields(buf, "next fails", "", true)
fmt.Println(err)
Output:

.1:vampire cannot write string as float64

func (PathError) Error added in v0.2.0

func (e PathError) Error() string

func (PathError) Unwrap added in v0.2.0

func (e PathError) Unwrap() error

type ReadBuffer

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

ReadBuffer adapts a Vampire encoded byte array to be used for read-only access. One has to use the specific Type that matches the encoded data to read the data from the buffer.

func NewReadBuffer

func NewReadBuffer(t Type, buf []byte, search bool) (*ReadBuffer, error)

NewReadBufferOffSize wraps buf for read access when the offsetSize is provided by a VMP Header in buf. When search is true NewReadBuffer scans for the first valid VMP header and uses it's offsetSize. Otherwise the VMP header must start at buf[0].

func NewReadBufferOffSize

func NewReadBufferOffSize(t Type, off SizeRange, buf []byte) (*ReadBuffer, error)

NewReadBufferOffSize wraps buf for read access when the offsetSize used for the encoded data is known. The first byte of the data of Type t must be buf[0].

func NewTypeReadBuffer

func NewTypeReadBuffer(buf []byte, search bool) (*ReadBuffer, error)

func NewTypeReadBufferOffSize

func NewTypeReadBufferOffSize(off SizeRange, buf []byte) (*ReadBuffer, error)

func (*ReadBuffer) AllBytes

func (b *ReadBuffer) AllBytes() []byte

func (*ReadBuffer) Bytes

func (b *ReadBuffer) Bytes() []byte

func (*ReadBuffer) Offset

func (b *ReadBuffer) Offset() SizeRange

func (*ReadBuffer) SliceFix

func (b *ReadBuffer) SliceFix(off uint) (revert uint)

func (*ReadBuffer) Unslice

func (b *ReadBuffer) Unslice(revert uint)

type RecordMarshaler

type RecordMarshaler interface {
	VampRecordWrite(*RecordType, *Buffer) error
}

type RecordType

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

TODO Slice to field

Example
r := struct {
	Name string
	Age  uint8
}{
	Name: "John Doe",
	Age:  44,
}
t, _ := TypeOf(r)
fmt.Println(t)
buf, _ := NewWriteBuffer(t, Size16, 0, nil)
t.Write(buf, r)
var out any
t.Read(&buf.ReadBuffer, &out)
fmt.Printf("%[1]T=%[1]v\n", out)
Output:

{Name:"Size16" Age:uint8}
[]interface {}=[John Doe 44]

func NewRecordType

func NewRecordType(fields ...Type) (*RecordType, error)

func (*RecordType) DynNo

func (t *RecordType) DynNo() uint

func (*RecordType) Equals

func (r *RecordType) Equals(t Type) bool

func (*RecordType) Field

func (t *RecordType) Field(buf *ReadBuffer, i uint) (revert uint)

func (*RecordType) FieldName

func (t *RecordType) FieldName(i uint) string

func (*RecordType) FieldType

func (t *RecordType) FieldType(i uint) Type

func (*RecordType) FixSize

func (t *RecordType) FixSize() uint

func (*RecordType) Hash

func (r *RecordType) Hash(h hash.Hash)

func (*RecordType) NumField

func (t *RecordType) NumField() uint

func (*RecordType) Read

func (t *RecordType) Read(buf *ReadBuffer, out any) (err error)

func (*RecordType) ReadFields

func (t *RecordType) ReadFields(buf *ReadBuffer, outs ...any) error

func (*RecordType) SetNames

func (t *RecordType) SetNames(ns ...string) *RecordType

func (*RecordType) String

func (t *RecordType) String() string

func (*RecordType) VampArrayFinish

func (t *RecordType) VampArrayFinish() error

func (*RecordType) VampArrayLen

func (t *RecordType) VampArrayLen() uint

func (*RecordType) VampArrayReader

func (t *RecordType) VampArrayReader(i uint) (any, error)

func (*RecordType) VampArrayResize

func (t *RecordType) VampArrayResize(l uint) error

func (*RecordType) VampArrayWriter

func (t *RecordType) VampArrayWriter(i uint) (any, error)

func (*RecordType) VampUnionAlt

func (t *RecordType) VampUnionAlt() (uint, any)

func (*RecordType) Write

func (t *RecordType) Write(buf *Buffer, values any) error

func (*RecordType) WriteFields

func (t *RecordType) WriteFields(buf *Buffer, values ...any) error

type RecordUnmarshaler

type RecordUnmarshaler interface {
	VampRecordRead(*RecordType, *ReadBuffer) error
}

type Reflect

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

func DefaultReflect

func DefaultReflect() Reflect

func (Reflect) ArraySize

func (r Reflect) ArraySize(s SizeRange) (res Reflect)

ignores invalid SizeRanges

func (Reflect) StringSize

func (r Reflect) StringSize(s SizeRange) (res Reflect)

ignores invalid SizeRanges

func (Reflect) TypeOf

func (r Reflect) TypeOf(val any) (Type, error)

type SizeRange

type SizeRange uint8

SizeRange defines the range that is used for buffer offsets, string length and any sort of ranges of size in byte that is used in Vampire encoding.

const (
	// Size8 is a 8-bit SizeRange with values 0…255
	Size8 SizeRange = iota

	// Size16 is a 16-bit SizeRange with values 0…65535
	Size16

	// Size32 is a 32-bit SizeRange with values 0…4294967295
	Size32
)

func (SizeRange) Check

func (s SizeRange) Check(size uint) error

Check checks if size is withing the SizeRange s. Only if size is not in s' range an error is returned.

func (SizeRange) Max

func (s SizeRange) Max() uint

Max returns the maximum uint of SizeRange s. SizeRange s is expected to be s.Valid()==true.

func (SizeRange) Size

func (s SizeRange) Size() uint

Size returns the number of bytes used for the size range in Vampire encoding. SizeRange s is expected to be s.Valid()==true.

func (SizeRange) String

func (i SizeRange) String() string

func (SizeRange) Valid

func (s SizeRange) Valid() bool

Valid returns true only for the supported size ranges as defined by the provided SizeRange constants.

func (*SizeRange) VampFromUint8

func (s *SizeRange) VampFromUint8(i uint8) error

SizeRange can be decoded from a Vampire Uint8.

func (SizeRange) VampToUint8

func (s SizeRange) VampToUint8() (uint8, error)

SizeRange can be encoded as Vampire Uint8.

type Type

type Type interface {
	FixSize() uint
	DynNo() uint
	Write(b *Buffer, value any) error
	Read(b *ReadBuffer, into any) error

	Equals(t Type) bool
	Hash(hash.Hash)

	fmt.Stringer
}

func ReadType

func ReadType(buf *ReadBuffer) (t Type, err error)

func TypeOf

func TypeOf(val any) (Type, error)
Example
type animal struct {
	Age    int      `vamp:"age,size=8"`
	Name   string   `vamp:",size=8"`
	Owners []string `vamp:",size=8:8"`
	Male   bool     `vamp:"-"`
}
t, err := TypeOf(animal{})
if err != nil {
	fmt.Println(err)
} else {
	fmt.Println(t.String())
}
Output:

{age:int8 Name:"Size8" Owners:[Size8 "Size8"]}

type UnionMarshaler

type UnionMarshaler interface {
	VampUnionAlt() (uint, any)
}

type UnionType

type UnionType struct {
	AltReader func(alt uint, into any) (reader any, err error)
	// contains filtered or unexported fields
}
Example
type address struct {
	Street string
	No     string
}
type geocoos struct {
	Lat, Lon float64
}
addrType, _ := TypeOf(address{})
geoType, _ := TypeOf(geocoos{})
placeType, _ := NewUnionType(Size8, addrType, geoType)
fmt.Println(placeType)
buf, _ := NewWriteBuffer(placeType, Size16, 0, nil)
placeType.Write(buf, Alt{S: 0, V: address{Street: "Justroad", No: "33a"}})
var out any
placeType.Read(&buf.ReadBuffer, &out)
fmt.Printf("%[1]T=%[1]v\n", out)
buf.Reset(placeType, Size16, 0)
placeType.Write(buf, Alt{S: 1, V: geocoos{Lat: 33.321, Lon: 44.123}})
placeType.Read(&buf.ReadBuffer, &out)
fmt.Printf("%[1]T=%[1]v\n", out)
Output:

<Size8 {Street:"Size16" No:"Size16"}|{Lat:float64 Lon:float64}>
[]interface {}=[Justroad 33a]
[]interface {}=[33.321 44.123]

func NewUnionType

func NewUnionType(altRange SizeRange, alts ...Type) (*UnionType, error)

func (*UnionType) Alt

func (t *UnionType) Alt(i uint) Type

func (*UnionType) AltRange

func (t *UnionType) AltRange() SizeRange

func (*UnionType) DynNo

func (t *UnionType) DynNo() uint

func (*UnionType) Equals

func (u *UnionType) Equals(t Type) bool

func (*UnionType) FixSize

func (t *UnionType) FixSize() uint

func (*UnionType) Hash

func (u *UnionType) Hash(h hash.Hash)

func (*UnionType) NumAlts

func (t *UnionType) NumAlts() uint

func (*UnionType) Read

func (t *UnionType) Read(buf *ReadBuffer, into any) error

func (*UnionType) ReadAlt

func (t *UnionType) ReadAlt(buf *ReadBuffer, selectVal func(uint) any) (any, error)

func (*UnionType) String

func (t *UnionType) String() string

func (*UnionType) VampRecordRead

func (t *UnionType) VampRecordRead(rt *RecordType, buf *ReadBuffer) error

func (*UnionType) VampRecordWrite

func (t *UnionType) VampRecordWrite(rt *RecordType, buf *Buffer) error

func (*UnionType) VampUnionAlt

func (t *UnionType) VampUnionAlt() (uint, any)

func (*UnionType) WithAltReader

func (t *UnionType) WithAltReader(f func(uint, any) (any, error)) *UnionType

func (*UnionType) Write

func (t *UnionType) Write(buf *Buffer, value any) error

func (*UnionType) WriteAlt

func (t *UnionType) WriteAlt(buf *Buffer, alt uint, value any) error

type UnionUnmarshaler

type UnionUnmarshaler interface {
	VampUnionReader(alt uint, into any) (any, error)
}

Directories

Path Synopsis
cmd
examples

Jump to

Keyboard shortcuts

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