glint

package module
v0.0.0-...-1742170 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2025 License: Apache-2.0 Imports: 12 Imported by: 0

README ΒΆ

logo

Glint

Glint brings binary serialization performance to Go without the complexity. Encode and decode your existing structs at speeds that match or exceed code-generated solutions.

Performance at a Glance

Encoding (ns/op)

Glint:     60 - 493
Protobuf:  174 - 1,509  
JSON:      694 - 84,330

Decoding (ns/op)

Glint:     185 - 775
Protobuf:  213 - 1,971
JSON:      3,921 - 510,590

Key Benefits

  • Zero allocations
  • Zero code generation
  • ~70% smaller than JSON
  • ~40% smaller than Protobuf
  • Works with existing structs

See detailed benchmarks for comprehensive performance data.

Quick Start

import "github.com/kungfusheep/glint"

// Define your struct - no special annotations required
type Person struct {
    Name string `glint:"name"`
    Age  int    `glint:"age"`
}

// Create encoder/decoder once, reuse many times
var (
    encoder = glint.NewEncoder[Person]()
    decoder = glint.NewDecoder[Person]()
)

// Encode
buffer := glint.NewBufferFromPool()
defer buffer.ReturnToPool()
encoder.Marshal(&Person{Name: "Alice", Age: 30}, buffer)

// Decode  
var person Person
err := decoder.Unmarshal(buffer.Bytes, &person)

Why Choose Glint?

πŸš€ Exceptional Performance
  • Sub-microsecond operations: As low as 60ns for simple structs
  • Zero allocations: Careful design eliminates heap allocations
  • Compact format: 70% smaller than JSON, 40% smaller than Protobuf
πŸ› οΈ Developer Friendly
  • No code generation: Work directly with your Go structs
  • No schema files: Self-describing format includes schemas
  • Simple API: Familiar Marshal/Unmarshal pattern
πŸ”„ Production Ready
  • Backward compatibility: Add fields freely, remove fields safely
  • Forward compatibility: Older versions ignore unknown fields
  • Type safety: Schema validation ensures type compatibility
  • Memory protection: Configurable limits prevent DoS attacks

Backward Compatibility

Glint's compatibility strategy is simple and powerful:

  • βœ… Add new fields - Older versions ignore them automatically
  • βœ… Remove fields - Newer versions handle missing fields gracefully
  • ❌ Change field types - The only breaking change (schema mismatch)

This approach gives you flexibility to evolve schemas naturally:

// Version 1
type User struct {
    ID   string `glint:"id"`
    Name string `glint:"name"`
}

// Version 2 - Safe to deploy alongside v1
type User struct {
    ID       string    `glint:"id"`
    Name     string    `glint:"name"`
    Email    string    `glint:"email"`     // New field - ignored by v1
    Created  time.Time `glint:"created"`   // New field - ignored by v1
    // Age int        `glint:"age"`       // Removed - v2 handles absence
}

No version numbers, no migration scripts - just natural schema evolution.

Installation

go get github.com/kungfusheep/glint

Core Concepts

Supported Types

Glint works with standard Go types out of the box:

  • Basic types: int/8/16/32/64, uint/8/16/32/64, float32/64, string, bool, time.Time
  • Composite types: structs, slices, maps
  • Pointers: Automatic nil handling
  • Custom types: Via MarshalBinary/UnmarshalBinary interfaces
Memory Protection

Glint provides configurable limits to prevent malicious inputs from exhausting memory:

// Custom limits for untrusted data
decoder := glint.NewDecoderWithLimits[MyStruct](glint.DecodeLimits{
    MaxByteSliceLen: 10 * 1024 * 1024,  // 10MB
    MaxStringLen:    1 * 1024 * 1024,   // 1MB
})
Struct Tags

Control field encoding with struct tags:

type User struct {
    ID        string    `glint:"id"`
    Secret    string                             // Skip this field
    Data      []byte    `glint:"data,copy"`      // Copy bytes instead of referencing
    CreatedAt time.Time `glint:"created_at"`
}
Custom Types

Implement custom encoding for your types:

type UUID [16]byte

func (u UUID) MarshalBinary() []byte {
    return u[:]
}

func (u *UUID) UnmarshalBinary(data []byte) {
    copy(u[:], data)
}

type User struct {
    ID UUID `glint:"id,encoder"`  // Uses custom encoding
}
Trust Mode (Schema Optimization)

For high-frequency communication between services, skip schema transmission:

// Server side - get trust header after first decode
trustHeader := glint.NewTrustHeader(decoder.impl)
response.Header.Set(trustHeader.Key(), trustHeader.Value())

// Client side - use trusted encoding
trustee := glint.HTTPTrustee(request)
buffer := glint.NewBufferWithTrust(trustee, encoder.impl)
encoder.Marshal(&data, buffer)  // Smaller payload, no schema
Manual Document Building

For dynamic document construction without structs:

doc := &glint.DocumentBuilder{}
doc.AppendString("name", "Alice").
    AppendInt("age", 30).
    AppendSlice("tags", glint.SliceBuilder{}.
        AppendStringSlice([]string{"admin", "user"}))

data := doc.Bytes()
Debugging Tools

Inspect Glint documents without decoding:

// Pretty print any Glint document
glint.Print(encodedData)

// Use with fmt for different formats
doc := glint.Document(encodedData)
fmt.Printf("%s", doc)   // Tree view
fmt.Printf("%+v", doc)  // Tree + hex
fmt.Printf("%x", doc)   // Raw hex

CLI Tool

Glint includes a powerful CLI for working with binary data:

go install github.com/kungfusheep/glint/cmd/glint@latest

# Inspect binary files
cat mydata.glint | glint

# Decode API responses
curl -s https://api.example.com/user | glint

# Extract specific fields
cat mydata.glint | glint get user.name

# Generate Go structs from data
cat mydata.glint | glint generate go package.StructName

See the CLI documentation for more features.

Use Cases

Glint excels in scenarios where:

  • Performance matters: High-throughput services, real-time systems
  • Schema flexibility is needed: Microservices with independent deployment
  • Storage is constrained: IoT devices, embedded systems, high-volume logging
  • Go-native solution preferred: No code generation

License

See LICENSE for details.

Documentation ΒΆ

Overview ΒΆ

Package glint implements a hierarchical binary serialization format

Example ΒΆ
package main

import (
	"fmt"
	"github.com/kungfusheep/glint"
)

func main() {
	// Define your struct
	type Person struct {
		Name string   `glint:"name"`
		Age  int      `glint:"age"`
		Tags []string `glint:"tags"`
	}

	// Create encoder and decoder once (thread-safe, reusable)
	encoder := glint.NewEncoder[Person]()
	decoder := glint.NewDecoder[Person]()

	// Create some data
	alice := Person{
		Name: "TestUser",
		Age:  32,
		Tags: []string{"engineer", "go", "serialization"},
	}

	// Encode to binary
	buffer := glint.NewBufferFromPool()
	defer buffer.ReturnToPool()

	encoder.Marshal(&alice, buffer)
	encoded := buffer.Bytes

	fmt.Printf("Encoded %d bytes\n", len(encoded))

	// Decode from binary
	var decoded Person
	err := decoder.Unmarshal(encoded, &decoded)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Decoded: %+v\n", decoded)
}
Output:
Encoded 60 bytes
Decoded: {Name:TestUser Age:32 Tags:[engineer go serialization]}

Index ΒΆ

Examples ΒΆ

Constants ΒΆ

View Source
const (
	Red    = "\033[91m"
	Orange = "\033[38;5;208m"
	Yellow = "\033[93m"
	Green  = "\033[92m"
	Blue   = "\033[94m"
	Purple = "\033[95m"
	Cyan   = "\033[96m"
	White  = "\033[97m"
	Reset  = "\033[0m"
)

Variables ΒΆ

View Source
var (
	ErrInvalidDocument = errors.New("invalid glint document")
	ErrSchemaNotFound  = errors.New("schema parse error. document was supplied with no schema and there are no cached instructions for the hash")
)

Unmarshal Errors

View Source
var DefaultLimits = DecodeLimits{
	MaxByteSliceLen: 100 * 1024 * 1024,
	MaxSliceInitCap: 10000,
	MaxSchemaSize:   1024 * 1024,
	MaxStringLen:    50 * 1024 * 1024,
}

DefaultLimits provides sensible defaults for most use cases

View Source
var ErrSkipVisit = errors.New("skip visit")

ErrSkipVisit is returned by a visitor to indicate that the walker should skip visiting the current field

Functions ΒΆ

func AppendDynamicValue ΒΆ

func AppendDynamicValue(v any, b *Buffer)

AppendDynamicValue encodes a value with type prefix into the buffer

func DynamicValue ΒΆ

func DynamicValue(value any) []byte

DynamicValue encodes any value to bytes with type information

func Flags ΒΆ

func Flags(document []byte) uint

Flags extracts the first byte containing document flags

func HashBytes ΒΆ

func HashBytes(document []byte) []byte

HashBytes extracts the 4-byte schema hash from a document header

func Print ΒΆ

func Print(bytes []byte) []byte

Print prints a document

func PrintMap ΒΆ

func PrintMap(r *Reader, schema *PrinterSchemaField, nestLevel int)

PrintMap prints a map within a document

func PrintSchema ΒΆ

func PrintSchema(schema *PrinterSchema, nestLevel int)

PrintSchema prints the schema of a document

func PrintSlice ΒΆ

func PrintSlice(r *Reader, field *PrinterSchemaField, nestLevel int)

PrintSlice prints a slice to stdout

func PrintStruct ΒΆ

func PrintStruct(r *Reader, schema *PrinterSchema, nestLevel int)

PrintStruct prints a struct within a document, or the top level of the document itself

func ReadDynamicBool ΒΆ

func ReadDynamicBool(b []byte) (bool, bool)

ReadDynamicBool reads a bool from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a bool

func ReadDynamicBoolSlice ΒΆ

func ReadDynamicBoolSlice(b []byte) ([]bool, bool)

ReadDynamicBoolSlice attempts to decode a []bool after checking the wire type. Returns false if the data doesn't represent a bool slice.

func ReadDynamicBytes ΒΆ

func ReadDynamicBytes(b []byte) ([]byte, bool)

ReadDynamicBytes reads a []byte from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []byte

func ReadDynamicBytesSlice ΒΆ

func ReadDynamicBytesSlice(b []byte) ([][]byte, bool)

ReadDynamicBytesSlice attempts to decode a [][]byte after checking the wire type. Returns false if the data doesn't represent a bytes slice.

func ReadDynamicFloat32 ΒΆ

func ReadDynamicFloat32(b []byte) (float32, bool)

ReadDynamicFloat32 reads a float32 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a float32

func ReadDynamicFloat32Slice ΒΆ

func ReadDynamicFloat32Slice(b []byte) ([]float32, bool)

ReadDynamicFloat32Slice attempts to decode a []float32 after checking the wire type. Returns false if the data doesn't represent a float32 slice.

func ReadDynamicFloat64 ΒΆ

func ReadDynamicFloat64(b []byte) (float64, bool)

ReadDynamicFloat64 reads a float64 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a float64

func ReadDynamicFloat64Slice ΒΆ

func ReadDynamicFloat64Slice(b []byte) ([]float64, bool)

ReadDynamicFloat64Slice attempts to decode a []float64 after checking the wire type. Returns false if the data doesn't represent a float64 slice.

func ReadDynamicInt ΒΆ

func ReadDynamicInt(b []byte) (int, bool)

ReadDynamicInt reads an int from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an int

func ReadDynamicInt8 ΒΆ

func ReadDynamicInt8(b []byte) (int8, bool)

ReadDynamicInt8 reads an int8 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an int8

func ReadDynamicInt8Slice ΒΆ

func ReadDynamicInt8Slice(b []byte) ([]int8, bool)

ReadDynamicInt8Slice reads a []int8 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []int8

func ReadDynamicInt16 ΒΆ

func ReadDynamicInt16(b []byte) (int16, bool)

ReadDynamicInt16 reads an int16 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an int16

func ReadDynamicInt16Slice ΒΆ

func ReadDynamicInt16Slice(b []byte) ([]int16, bool)

ReadDynamicInt16Slice reads a []int16 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []int16

func ReadDynamicInt32 ΒΆ

func ReadDynamicInt32(b []byte) (int32, bool)

ReadDynamicInt32 reads an int32 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an int32

func ReadDynamicInt32Slice ΒΆ

func ReadDynamicInt32Slice(b []byte) ([]int32, bool)

ReadDynamicInt32Slice reads a []int32 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []int32

func ReadDynamicInt64 ΒΆ

func ReadDynamicInt64(b []byte) (int64, bool)

ReadDynamicInt64 reads an int64 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an int64

func ReadDynamicInt64Slice ΒΆ

func ReadDynamicInt64Slice(b []byte) ([]int64, bool)

ReadDynamicInt64Slice reads a []int64 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []int64

func ReadDynamicIntSlice ΒΆ

func ReadDynamicIntSlice(b []byte) ([]int, bool)

ReadDynamicIntSlice reads a []int from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []int

func ReadDynamicSlice ΒΆ

func ReadDynamicSlice(r *Reader, wire WireType) any

ReadDynamicSlice decodes a typed slice after examining the wire type

func ReadDynamicString ΒΆ

func ReadDynamicString(b []byte) (string, bool)

ReadDynamicString reads a string from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a string

func ReadDynamicStringSlice ΒΆ

func ReadDynamicStringSlice(b []byte) ([]string, bool)

ReadDynamicStringSlice reads a []string from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []string

func ReadDynamicTime ΒΆ

func ReadDynamicTime(b []byte) (time.Time, bool)

ReadDynamicTime reads a time.Time from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a time.Time

func ReadDynamicTimeSlice ΒΆ

func ReadDynamicTimeSlice(b []byte) ([]time.Time, bool)

ReadDynamicTimeSlice attempts to decode a []time.Time after checking the wire type. Returns false if the data doesn't represent a time slice.

func ReadDynamicUint ΒΆ

func ReadDynamicUint(b []byte) (uint, bool)

ReadDynamicUint reads an uint from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an uint

func ReadDynamicUint8 ΒΆ

func ReadDynamicUint8(b []byte) (uint8, bool)

ReadDynamicUint8 reads an uint8 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an uint8

func ReadDynamicUint8Slice ΒΆ

func ReadDynamicUint8Slice(b []byte) ([]uint8, bool)

ReadDynamicUint8Slice reads a []uint8 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []uint8

func ReadDynamicUint16 ΒΆ

func ReadDynamicUint16(b []byte) (uint16, bool)

ReadDynamicUint16 reads an uint16 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an uint16

func ReadDynamicUint16Slice ΒΆ

func ReadDynamicUint16Slice(b []byte) ([]uint16, bool)

ReadDynamicUint16Slice reads a []uint16 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []uint16

func ReadDynamicUint32 ΒΆ

func ReadDynamicUint32(b []byte) (uint32, bool)

ReadDynamicUint32 reads an uint32 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an uint32

func ReadDynamicUint32Slice ΒΆ

func ReadDynamicUint32Slice(b []byte) ([]uint32, bool)

ReadDynamicUint32Slice reads a []uint32 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []uint32

func ReadDynamicUint64 ΒΆ

func ReadDynamicUint64(b []byte) (uint64, bool)

ReadDynamicUint64 reads an uint64 from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not an uint64

func ReadDynamicUint64Slice ΒΆ

func ReadDynamicUint64Slice(b []byte) ([]uint64, bool)

ReadDynamicUint64Slice attempts to decode a []uint64 after checking the wire type. Returns false if the data doesn't represent a uint64 slice.

func ReadDynamicUintSlice ΒΆ

func ReadDynamicUintSlice(b []byte) ([]uint, bool)

ReadDynamicUintSlice reads a []uint from a byte array based on the wire type provided by reading the first varint, it will return false if the wire type was not a []uint

func ReadDynamicValue ΒΆ

func ReadDynamicValue(b []byte) any

ReadDynamicValue decodes a value using the wire type from the first varint

func ReadDynamicValueFromReader ΒΆ

func ReadDynamicValueFromReader(r *Reader) any

ReadDynamicValueFromReader extracts a typed value after reading the wire type indicator

func SPrint ΒΆ

func SPrint(bytes []byte) string

SPrint returns a string representation of a glint document, similar to Print but returns the string instead of printing to stdout

func SPrintMap ΒΆ

func SPrintMap(r *Reader, schema *PrinterSchemaField, nestLevel int) string

SPrintMap returns a string representation of a map

func SPrintSlice ΒΆ

func SPrintSlice(r *Reader, field *PrinterSchemaField, nestLevel int) string

SPrintSlice returns a string representation of a slice

func SPrintStruct ΒΆ

func SPrintStruct(r *Reader, schema *PrinterSchema, nestLevel int) string

SPrintStruct returns a string representation of a struct within a document

func SPrintStructVerbose ΒΆ

func SPrintStructVerbose(r *Reader, schema *PrinterSchema, nestLevel int, printBytes bool) string

SPrintStructVerbose returns a string representation of a struct within a document with the option to print the bytes for values

func SPrintStructVerboseWithColors ΒΆ

func SPrintStructVerboseWithColors(r *Reader, schema *PrinterSchema, nestLevel int, printBytes bool, useColors bool) string

SPrintStructVerboseWithColors returns a string representation of a struct with optional color support

func SPrintStructWithColors ΒΆ

func SPrintStructWithColors(r *Reader, schema *PrinterSchema, nestLevel int, useColors bool) string

SPrintStructWithColors returns a string representation of a struct with optional color support

func SchemaBytes ΒΆ

func SchemaBytes(t any) []byte

SchemaBytes generates a binary schema from struct tags marked 'glint'

func SchemaBytesUsingTag ΒΆ

func SchemaBytesUsingTag(t any, tagName string) []byte

SchemaBytesUsingTag creates a schema using custom field tag names

func Walk ΒΆ

func Walk(doc []byte, visitor Visitor) error

func WireTypeToReflectType ΒΆ

func WireTypeToReflectType(k WireType) reflect.Type

WireTypeToReflectType converts glint wire types back to Go reflection types

Types ΒΆ

type Buffer ΒΆ

type Buffer struct {
	Bytes         []byte
	TrustedSchema bool // when true, omits schema body for trusted connections
}

Buffer accumulates encoded data during serialization. Supports only append operations for efficiency.

func NewBufferFromPool ΒΆ

func NewBufferFromPool() *Buffer

NewBufferFromPool obtains a reset Buffer from the pool. Call ReturnToPool when finished. For existing memory, create directly: `buf := Buffer{mySlice[:0]}` - pooling is optional.

func NewBufferFromPoolWithCap ΒΆ

func NewBufferFromPoolWithCap(size int) *Buffer

NewBufferFromPoolWithCap acquires a pooled Buffer with guaranteed capacity. Call ReturnToPool after use.

func NewBufferWithTrust ΒΆ

func NewBufferWithTrust(r Trustee, e *encoderImpl) *Buffer

NewBufferWithTrust acquires a pooled Buffer and enables trust mode if schema hashes match. Remember to call ReturnToPool after use.

func (*Buffer) AppendBool ΒΆ

func (b *Buffer) AppendBool(value bool)

AppendBool encodes a boolean as a single byte: 1 for true, 0 for false.

func (*Buffer) AppendBytes ΒΆ

func (b *Buffer) AppendBytes(value []byte)

AppendBytes encodes a byte slice with length prefix into the buffer.

func (*Buffer) AppendFloat32 ΒΆ

func (b *Buffer) AppendFloat32(value float32)

AppendFloat32 encodes a float32 by converting to uint32 bits

func (*Buffer) AppendFloat64 ΒΆ

func (b *Buffer) AppendFloat64(value float64)

AppendFloat64 encodes a float64 by converting to uint64 bits

func (*Buffer) AppendInt ΒΆ

func (b *Buffer) AppendInt(value int)

AppendInt encodes a signed int using zigzag encoding.

func (*Buffer) AppendInt8 ΒΆ

func (b *Buffer) AppendInt8(value int8)

AppendInt8 adds a signed byte to the buffer.

func (*Buffer) AppendInt16 ΒΆ

func (b *Buffer) AppendInt16(value int16)

AppendInt16 encodes a signed int16 using zigzag encoding.

func (*Buffer) AppendInt32 ΒΆ

func (b *Buffer) AppendInt32(value int32)

AppendInt32 encodes a signed int32 using zigzag encoding.

func (*Buffer) AppendInt64 ΒΆ

func (b *Buffer) AppendInt64(value int64)

AppendInt64 encodes a signed int64 as a variable-length integer.

func (*Buffer) AppendString ΒΆ

func (b *Buffer) AppendString(value string)

AppendString encodes a string with length prefix into the buffer.

func (*Buffer) AppendTime ΒΆ

func (b *Buffer) AppendTime(t time.Time)

AppendTime encodes a time value using Go's binary marshaling

func (*Buffer) AppendUint ΒΆ

func (b *Buffer) AppendUint(value uint)

AppendUint encodes a uint as a variable-length integer.

func (*Buffer) AppendUint8 ΒΆ

func (b *Buffer) AppendUint8(value uint8)

AppendUint8 adds a single byte to the buffer.

func (*Buffer) AppendUint16 ΒΆ

func (b *Buffer) AppendUint16(value uint16)

AppendUint16 encodes a uint16 as a variable-length integer.

func (*Buffer) AppendUint32 ΒΆ

func (b *Buffer) AppendUint32(value uint32)

AppendUint32 encodes a uint32 as a variable-length integer.

func (*Buffer) AppendUint64 ΒΆ

func (b *Buffer) AppendUint64(value uint64)

AppendUint64 encodes a uint64 as a variable-length integer.

func (*Buffer) Reset ΒΆ

func (b *Buffer) Reset()

Reset clears the buffer contents but preserves allocated memory

func (*Buffer) ReturnToPool ΒΆ

func (b *Buffer) ReturnToPool()

ReturnToPool releases the buffer back to the pool. Using the buffer after this call results in undefined behavior.

type DecodeInstructionLookup ΒΆ

type DecodeInstructionLookup struct {
	Added func(hash uint, contextID uint) // a callback to be told when an item has been added to the lookup along with a context ID
	// contains filtered or unexported fields
}

DecodeInstructionLookup is the data structre we use for doing lookups of small names. there is a tipping point where this becomes less effective than a simple string map - see `smallThresh` for that threshold

type DecodeLimits ΒΆ

type DecodeLimits struct {
	MaxByteSliceLen uint // Maximum byte slice length (0 = unlimited)
	MaxSliceInitCap uint // Cap initial slice allocations to prevent huge upfront allocations
	MaxSchemaSize   uint // Maximum schema size in bytes
	MaxStringLen    uint // Maximum string length
}

DecodeLimits configures bounds checking during decoding to prevent memory exhaustion attacks

type Decoder ΒΆ

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

Decoder handles type-safe decoding of type T

Example ΒΆ
type child struct {
	Name string `glint:"name"`
}

type Example struct {
	Bool    bool      `glint:"bool"`
	Int     int       `glint:"int"`
	Int8    int8      `glint:"int8"`
	Int16   int16     `glint:"int16"`
	Int32   int32     `glint:"int32"`
	Int64   int64     `glint:"int64"`
	Uint    uint      `glint:"uint"`
	Uint8   uint8     `glint:"uint8"`
	Uint16  uint16    `glint:"uint16"`
	Uint32  uint32    `glint:"uint32"`
	Uint64  uint64    `glint:"uint64"`
	Float32 float32   `glint:"float32"`
	Float64 float64   `glint:"float64"`
	String  string    `glint:"string"`
	Bytes   []byte    `glint:"bytes"`
	Struct  child     `glint:"struct"`
	Time    time.Time `glint:"time"`
}

test := Example{
	Bool:    true,
	Int:     -42,
	Int8:    -8,
	Int16:   -2048,
	Int32:   -1024,
	Int64:   -9223372036854775808,
	Uint:    42,
	Uint8:   8,
	Uint16:  2048,
	Uint32:  1024,
	Uint64:  9223372036854775807,
	Float32: 3.14,
	Float64: 3.142069,
	String:  "greetings",
	Bytes:   []byte{42, 7, 255},
	Struct: child{
		Name: "TestUser",
	},
	Time: time.Now(),
}

encoder := newEncoder(Example{})

buf := Buffer{}

encoder.Marshal(&test, &buf)

// fmt.Println(buf.Bytes)
// Print(buf.Bytes)

/// Output:
// 1

func NewDecoder ΒΆ

func NewDecoder[T any]() *Decoder[T]

NewDecoder constructs a decoder specialized for type T with default limits

func NewDecoderUsingTag ΒΆ

func NewDecoderUsingTag[T any](usingTagName string) *Decoder[T]

NewDecoderUsingTag is primarily for internal use. Like NewDecoder but accepts a custom struct tag name for framework integration (e.g. "rpc").

func NewDecoderWithLimits ΒΆ

func NewDecoderWithLimits[T any](limits DecodeLimits) *Decoder[T]

NewDecoderWithLimits constructs a decoder with custom bounds checking limits

func (*Decoder[T]) Unmarshal ΒΆ

func (d *Decoder[T]) Unmarshal(bytes []byte, v *T) error

Unmarshal extracts data from bytes into a value of type T

func (*Decoder[T]) UnmarshalWithContext ΒΆ

func (d *Decoder[T]) UnmarshalWithContext(bytes []byte, v *T, context DecoderContext) error

UnmarshalWithContext performs decoding using the supplied context

type DecoderContext ΒΆ

type DecoderContext struct {
	InstructionCache *DecodeInstructionLookup
	ID               uint
}

DecoderContext supports trusted schema mode with an instruction cache and caller-defined affinity ID

type Document ΒΆ

type Document []byte

Document is a type alias for []byte that implements fmt.Formatter for pretty printing glint documents

func (Document) Format ΒΆ

func (d Document) Format(f fmt.State, verb rune)

Format implements fmt.Formatter interface for custom formatting verbs

func (Document) String ΒΆ

func (d Document) String() string

String implements fmt.Stringer interface

type DocumentBuilder ΒΆ

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

DocumentBuilder is a simple inline progressive builder. You add your properties and it builds the document up as you go along.

Example ΒΆ
package main

import (
	"github.com/kungfusheep/glint"
)

func main() {
	// Build documents without structs
	doc := &glint.DocumentBuilder{}

	doc.AppendString("name", "SampleUser").
		AppendInt("age", 25).
		AppendBool("active", true)

	data := doc.Bytes()

	// Print human-readable format
	glint.Print(data)

	// Output shows tree structure (actual output may vary):
	// Glint Document
	// β”œβ”€ Schema
	// β”‚  β”œβ”€ String: name
	// β”‚  β”œβ”€ Int: age
	// β”‚  └─ Bool: active
	// └─ Values
	//    β”œβ”€ name: SampleUser
	//    β”œβ”€ age: 25
	//    └─ active: true
}

func (*DocumentBuilder) AppendBool ΒΆ

func (d *DocumentBuilder) AppendBool(name string, value bool) *DocumentBuilder

AppendBool adds a bool field to the document against a given name

func (*DocumentBuilder) AppendBytes ΒΆ

func (d *DocumentBuilder) AppendBytes(name string, value []byte) *DocumentBuilder

AppendBytes adds a bytes field to the document against a given name

func (*DocumentBuilder) AppendFloat32 ΒΆ

func (d *DocumentBuilder) AppendFloat32(name string, value float32) *DocumentBuilder

AppendFloat32 adds a float32 field to the document against a given name

func (*DocumentBuilder) AppendFloat64 ΒΆ

func (d *DocumentBuilder) AppendFloat64(name string, value float64) *DocumentBuilder

AppendFloat64 adds a float64 field to the document against a given name

func (*DocumentBuilder) AppendInt ΒΆ

func (d *DocumentBuilder) AppendInt(name string, value int) *DocumentBuilder

AppendInt adds a int field to the document against a given name

func (*DocumentBuilder) AppendInt8 ΒΆ

func (d *DocumentBuilder) AppendInt8(name string, value int8) *DocumentBuilder

AppendInt8 adds a int8 field to the document against a given name

func (*DocumentBuilder) AppendInt16 ΒΆ

func (d *DocumentBuilder) AppendInt16(name string, value int16) *DocumentBuilder

AppendInt16 adds a int16 field to the document against a given name

func (*DocumentBuilder) AppendInt32 ΒΆ

func (d *DocumentBuilder) AppendInt32(name string, value int32) *DocumentBuilder

AppendInt32 adds a int32 field to the document against a given name

func (*DocumentBuilder) AppendInt64 ΒΆ

func (d *DocumentBuilder) AppendInt64(name string, value int64) *DocumentBuilder

AppendInt64 adds a int64 field to the document against a given name

func (*DocumentBuilder) AppendNestedDocument ΒΆ

func (d *DocumentBuilder) AppendNestedDocument(name string, value *DocumentBuilder) *DocumentBuilder

AppendNestedDocument appends another document within this one. Equivalent of a nested struct.

func (*DocumentBuilder) AppendSlice ΒΆ

func (d *DocumentBuilder) AppendSlice(name string, value SliceBuilder) *DocumentBuilder

AppendSlice adds a slice field to the document against a given name

func (*DocumentBuilder) AppendString ΒΆ

func (d *DocumentBuilder) AppendString(name, value string) *DocumentBuilder

AppendString adds a string field to the document against a given name

func (*DocumentBuilder) AppendTime ΒΆ

func (d *DocumentBuilder) AppendTime(name string, value time.Time) *DocumentBuilder

AppendTime adds a time field to the document against a given name

func (*DocumentBuilder) AppendUint ΒΆ

func (d *DocumentBuilder) AppendUint(name string, value uint) *DocumentBuilder

AppendUint adds a uint field to the document against a given name

func (*DocumentBuilder) AppendUint8 ΒΆ

func (d *DocumentBuilder) AppendUint8(name string, value uint8) *DocumentBuilder

AppendUint8 adds a uint8 field to the document against a given name

func (*DocumentBuilder) AppendUint16 ΒΆ

func (d *DocumentBuilder) AppendUint16(name string, value uint16) *DocumentBuilder

AppendUint16 adds a uint16 field to the document against a given name

func (*DocumentBuilder) AppendUint32 ΒΆ

func (d *DocumentBuilder) AppendUint32(name string, value uint32) *DocumentBuilder

AppendUint32 adds a uint32 field to the document against a given name

func (*DocumentBuilder) AppendUint64 ΒΆ

func (d *DocumentBuilder) AppendUint64(name string, value uint64) *DocumentBuilder

AppendUint64 adds a uint64 field to the document against a given name

func (*DocumentBuilder) Bytes ΒΆ

func (d *DocumentBuilder) Bytes() []byte

Bytes returns the document as a byte array

func (*DocumentBuilder) WriteTo ΒΆ

func (d *DocumentBuilder) WriteTo(b *Buffer)

WriteTo writes the document to a buffer

type Encoder ΒΆ

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

Encoder handles type-safe encoding of type T

Example ΒΆ
type Point struct {
	X int `glint:"x"`
	Y int `glint:"y"`
}

encoder := newEncoder(Point{})

buf := NewBufferFromPool()
value := Point{
	X: 10,
	Y: 55,
}

encoder.Marshal(&value, buf)

fmt.Println(buf.Bytes)
Output:
[0 59 198 217 19 6 2 1 120 2 1 121 20 110]
Example (Generic) ΒΆ
// Create a type-safe encoder for Person
encoder := NewEncoder[Person]()

// Create a person
person := Person{Name: "SampleUser", Age: 30}

// Encode the person
buf := NewBufferFromPool()
encoder.Marshal(&person, buf)

// Create a type-safe decoder for Person
decoder := NewDecoder[Person]()

// Decode into a new person
var decoded Person
err := decoder.Unmarshal(buf.Bytes, &decoded)
if err != nil {
	panic(err)
}

fmt.Printf("%s is %d years old\n", decoded.Name, decoded.Age)
Output:
SampleUser is 30 years old
Example (SliceGeneric) ΒΆ
// Create a type-safe encoder for People (which contains a slice)
encoder := NewEncoder[People]()

// Create some people
people := People{
	Items: []Person{
		{Name: "ExampleUser", Age: 25},
		{Name: "Carol", Age: 35},
	},
}

// Encode the people
buf := NewBufferFromPool()
encoder.Marshal(&people, buf)

// Create a type-safe decoder for People
decoder := NewDecoder[People]()

// Decode into a new People struct
var decoded People
err := decoder.Unmarshal(buf.Bytes, &decoded)
if err != nil {
	panic(err)
}

for _, p := range decoded.Items {
	fmt.Printf("%s is %d years old\n", p.Name, p.Age)
}
Output:
ExampleUser is 25 years old
Carol is 35 years old

func NewEncoder ΒΆ

func NewEncoder[T any]() *Encoder[T]

NewEncoder builds an Encoder using type information extracted from a blank struct instance. Create only ONE encoder per type - the encoder is safe for concurrent use. The blank struct's type must exactly match what you'll pass to Marshal. e.g mystructEncoder := glint.NewEncoder(mystruct{})

Fields that we wish to encode, on `mystruct` in the example above, carry tags that look like this

type mystruct struct {
	name string `glint:"name"`
	age  uint8  `glint:"age"`
}

When `Marshal` encodes data into the Buffer, these tag names are used as the schema field names

func (*Encoder[T]) ClearSchema ΒΆ

func (e *Encoder[T]) ClearSchema()

ClearSchema wipes all schema data from this encoder.

func (*Encoder[T]) Marshal ΒΆ

func (e *Encoder[T]) Marshal(v *T, buf *Buffer)

Marshal encodes a value of type T into the supplied buffer

func (*Encoder[T]) Schema ΒΆ

func (e *Encoder[T]) Schema() *Buffer

Schema retrieves this encoder's schema, excluding version and hash bytes

type PrinterDocument ΒΆ

type PrinterDocument struct {
	Flags  byte
	CRC32  []byte
	Schema Reader
	Body   Reader
}

PrinterDocument represents the top level parts of a glint document, intended for tooling purposes.

func NewPrinterDocument ΒΆ

func NewPrinterDocument(r *Reader) PrinterDocument

NewPrinterDocument reads a document from a Reader and returns a PrinterDocument

type PrinterSchema ΒΆ

type PrinterSchema struct {
	Fields []PrinterSchemaField

	NestedSchema *PrinterSchema
}

PrinterSchema represents the schema of a glint document, intended for tooling purposes.

func NewPrinterSchema ΒΆ

func NewPrinterSchema(r *Reader) PrinterSchema

NewPrinterSchema reads a schema from a Reader and returns a PrinterSchema

type PrinterSchemaField ΒΆ

type PrinterSchemaField struct {
	TypeID WireType
	Name   string

	IsSlice   bool
	IsPointer bool

	NestedSchema *PrinterSchema

	NestedSlice *PrinterSchemaField

	MapType [2]WireType
}

PrinterSchemaField represents a single field in a schema, intended for tooling purposes.

func NewPrinterSchemaField ΒΆ

func NewPrinterSchemaField(r *Reader) PrinterSchemaField

NewPrinterSchemaField reads a single field from a Reader and returns a PrinterSchemaField

func NewRawPrinterSchemaField ΒΆ

func NewRawPrinterSchemaField(r *Reader) PrinterSchemaField

NewRawPrinterSchemaField is almost identical to NewPrinterSchemaField except it doesn't read a name. Used for when parsing nested struct schemas like arrays or maps.

func (*PrinterSchemaField) ReadSubSchema ΒΆ

func (f *PrinterSchemaField) ReadSubSchema(r *Reader)

ReadSubSchema reads a nested schema from a Reader and sets it on the PrinterSchemaField

type Reader ΒΆ

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

Reader provides sequential access to encoded data with position tracking.

func NewReader ΒΆ

func NewReader(b []byte) Reader

func (*Reader) BytesFromMark ΒΆ

func (r *Reader) BytesFromMark() []byte

BytesFromMark extracts data between the saved position and current location

func (*Reader) BytesLeft ΒΆ

func (r *Reader) BytesLeft() uint

BytesLeft calculates remaining unread bytes

func (*Reader) Mark ΒΆ

func (r *Reader) Mark() uint

Mark retrieves the saved position value

func (*Reader) Read ΒΆ

func (r *Reader) Read(l uint) []byte

Read extracts the specified number of bytes

func (*Reader) ReadBool ΒΆ

func (r *Reader) ReadBool() bool

ReadBool interprets a byte as boolean: 1 = true, 0 = false.

func (*Reader) ReadBoolSlice ΒΆ

func (r *Reader) ReadBoolSlice() []bool

ReadBoolSlice decodes an array of boolean values

func (*Reader) ReadByte ΒΆ

func (r *Reader) ReadByte() byte

ReadByte extracts the next byte

func (*Reader) ReadBytesSlice ΒΆ

func (r *Reader) ReadBytesSlice() [][]byte

ReadBytesSlice decodes a collection of length-prefixed byte arrays

func (*Reader) ReadFloat32 ΒΆ

func (r *Reader) ReadFloat32() float32

ReadFloat32 decodes a float32 from its uint32 bit representation

func (*Reader) ReadFloat32Slice ΒΆ

func (r *Reader) ReadFloat32Slice() []float32

ReadFloat32Slice decodes multiple float32 values

func (*Reader) ReadFloat64 ΒΆ

func (r *Reader) ReadFloat64() float64

ReadFloat64 decodes a float64 from its uint64 bit representation

func (*Reader) ReadFloat64Slice ΒΆ

func (r *Reader) ReadFloat64Slice() []float64

ReadFloat64Slice retrieves an array of float64 values

func (*Reader) ReadInt ΒΆ

func (r *Reader) ReadInt() int

ReadInt decodes a zigzag-encoded int

func (*Reader) ReadInt8 ΒΆ

func (r *Reader) ReadInt8() int8

ReadInt8 extracts a signed byte

func (*Reader) ReadInt8Slice ΒΆ

func (r *Reader) ReadInt8Slice() []int8

ReadInt8Slice extracts an array of signed bytes

func (*Reader) ReadInt16 ΒΆ

func (r *Reader) ReadInt16() int16

ReadInt16 decodes a zigzag-encoded int16

func (*Reader) ReadInt16Slice ΒΆ

func (r *Reader) ReadInt16Slice() []int16

ReadInt16Slice retrieves multiple zigzag-encoded int16s

func (*Reader) ReadInt32 ΒΆ

func (r *Reader) ReadInt32() int32

ReadInt32 decodes a zigzag-encoded int32

func (*Reader) ReadInt32Slice ΒΆ

func (r *Reader) ReadInt32Slice() []int32

ReadInt32Slice decodes a collection of zigzag-encoded int32s

func (*Reader) ReadInt64 ΒΆ

func (r *Reader) ReadInt64() int64

ReadInt64 decodes a variable-length int64

func (*Reader) ReadInt64Slice ΒΆ

func (r *Reader) ReadInt64Slice() []int64

ReadInt64Slice extracts an array of variable-length int64s

func (*Reader) ReadIntSlice ΒΆ

func (r *Reader) ReadIntSlice() []int

ReadIntSlice decodes an array of zigzag-encoded ints

func (*Reader) ReadString ΒΆ

func (r *Reader) ReadString() string

ReadString decodes a length-prefixed string

func (*Reader) ReadStringSlice ΒΆ

func (r *Reader) ReadStringSlice() []string

ReadStringSlice decodes a length-prefixed array of strings

func (*Reader) ReadTime ΒΆ

func (r *Reader) ReadTime() time.Time

ReadTime decodes a binary-marshaled time value

func (*Reader) ReadTimeSlice ΒΆ

func (r *Reader) ReadTimeSlice() []time.Time

ReadTimeSlice extracts multiple binary-encoded time values

func (*Reader) ReadUint ΒΆ

func (r *Reader) ReadUint() uint

ReadUint decodes a variable-length uint

func (*Reader) ReadUint8 ΒΆ

func (r *Reader) ReadUint8() uint8

ReadUint8 extracts a single byte

func (*Reader) ReadUint8Slice ΒΆ

func (r *Reader) ReadUint8Slice() []uint8

ReadUint8Slice returns a byte slice of the specified length

func (*Reader) ReadUint16 ΒΆ

func (r *Reader) ReadUint16() uint16

ReadUint16 decodes a variable-length uint16

func (*Reader) ReadUint16Slice ΒΆ

func (r *Reader) ReadUint16Slice() []uint16

ReadUint16Slice decodes an array of variable-length uint16s

func (*Reader) ReadUint32 ΒΆ

func (r *Reader) ReadUint32() uint32

ReadUint32 decodes a variable-length uint32

func (*Reader) ReadUint32Slice ΒΆ

func (r *Reader) ReadUint32Slice() []uint32

ReadUint32Slice extracts multiple uint32 values

func (*Reader) ReadUint64 ΒΆ

func (r *Reader) ReadUint64() uint64

ReadUint64 decodes a variable-length uint64

func (*Reader) ReadUint64Slice ΒΆ

func (r *Reader) ReadUint64Slice() []uint64

ReadUint64Slice decodes a sequence of uint64 values

func (*Reader) ReadUintSlice ΒΆ

func (r *Reader) ReadUintSlice() []uint

ReadUintSlice extracts an array of variable-length uints

func (*Reader) ReadVarint ΒΆ

func (r *Reader) ReadVarint() uint

func (*Reader) ReadZigzagVarint ΒΆ

func (r *Reader) ReadZigzagVarint() int

ReadZigzagVarint decodes a zigzag-encoded variable integer.

func (*Reader) Remaining ΒΆ

func (r *Reader) Remaining() []byte

Remaining provides all unread data as a slice

func (*Reader) ResetMark ΒΆ

func (r *Reader) ResetMark()

ResetMark jumps back to the saved position

func (*Reader) SetMark ΒΆ

func (r *Reader) SetMark()

SetMark saves the current position for later reference

func (*Reader) Skip ΒΆ

func (r *Reader) Skip(l uint)

Skip moves forward without extracting data

func (*Reader) SkipVarint ΒΆ

func (r *Reader) SkipVarint()

SkipVarint bypasses a variable-length integer without decoding

func (*Reader) Unread ΒΆ

func (r *Reader) Unread(l uint)

Unread moves backward by the specified amount

type SliceBuilder ΒΆ

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

SliceBuilder can build various types of glint slices and be appended into a DocumentBuilder

func (*SliceBuilder) AppendBoolSlice ΒΆ

func (s *SliceBuilder) AppendBoolSlice(value []bool)

AppendBoolSlice appends a bool slice to this slice builder

func (*SliceBuilder) AppendBytesSlice ΒΆ

func (s *SliceBuilder) AppendBytesSlice(value [][]byte)

AppendBytesSlice appends a bytes slice to this slice builder

func (*SliceBuilder) AppendFloat32Slice ΒΆ

func (s *SliceBuilder) AppendFloat32Slice(value []float32)

AppendFloat32Slice appends a float32 slice to this slice builder

func (*SliceBuilder) AppendFloat64Slice ΒΆ

func (s *SliceBuilder) AppendFloat64Slice(value []float64)

AppendFloat64Slice appends a float64 slice to this slice builder

func (*SliceBuilder) AppendInt8Slice ΒΆ

func (s *SliceBuilder) AppendInt8Slice(value []int8)

AppendInt8Slice appends a int8 slice to this slice builder

func (*SliceBuilder) AppendInt16Slice ΒΆ

func (s *SliceBuilder) AppendInt16Slice(value []int16)

AppendInt16Slice appends a int16 slice to this slice builder

func (*SliceBuilder) AppendInt16SliceDelta ΒΆ

func (s *SliceBuilder) AppendInt16SliceDelta(value []int16)

AppendInt16SliceDelta appends a int16 slice using delta encoding

func (*SliceBuilder) AppendInt32Slice ΒΆ

func (s *SliceBuilder) AppendInt32Slice(value []int32)

AppendInt32Slice appends a int32 slice to this slice builder

func (*SliceBuilder) AppendInt32SliceDelta ΒΆ

func (s *SliceBuilder) AppendInt32SliceDelta(value []int32)

AppendInt32SliceDelta appends a int32 slice using delta encoding

func (*SliceBuilder) AppendInt64Slice ΒΆ

func (s *SliceBuilder) AppendInt64Slice(value []int64)

AppendInt64Slice appends a int64 slice to this slice builder

func (*SliceBuilder) AppendInt64SliceDelta ΒΆ

func (s *SliceBuilder) AppendInt64SliceDelta(value []int64)

AppendInt64SliceDelta appends a int64 slice using delta encoding

func (*SliceBuilder) AppendIntSlice ΒΆ

func (s *SliceBuilder) AppendIntSlice(value []int)

AppendIntSlice appends a int slice to this slice builder

func (*SliceBuilder) AppendIntSliceDelta ΒΆ

func (s *SliceBuilder) AppendIntSliceDelta(value []int)

AppendIntSliceDelta appends a int slice using delta encoding

func (*SliceBuilder) AppendNestedDocumentSlice ΒΆ

func (s *SliceBuilder) AppendNestedDocumentSlice(value []DocumentBuilder)

AppendNestedDocumentSlice appends a nesteddocument slice

func (*SliceBuilder) AppendSlice ΒΆ

func (s *SliceBuilder) AppendSlice(value []SliceBuilder)

func (*SliceBuilder) AppendStringSlice ΒΆ

func (s *SliceBuilder) AppendStringSlice(value []string)

AppendStringSlice appends a string slice to this slice builder

func (*SliceBuilder) AppendTimeSlice ΒΆ

func (s *SliceBuilder) AppendTimeSlice(value []time.Time)

AppendTimeSlice appends a time slice to this slice builder

func (*SliceBuilder) AppendUint8Slice ΒΆ

func (s *SliceBuilder) AppendUint8Slice(value []uint8)

AppendUint8Slice appends a uint8 slice to this slice builder

func (*SliceBuilder) AppendUint16Slice ΒΆ

func (s *SliceBuilder) AppendUint16Slice(value []uint16)

AppendUint16Slice appends a uint16 slice to this slice builder

func (*SliceBuilder) AppendUint16SliceDelta ΒΆ

func (s *SliceBuilder) AppendUint16SliceDelta(value []uint16)

AppendUint16SliceDelta appends a uint16 slice using delta encoding

func (*SliceBuilder) AppendUint32Slice ΒΆ

func (s *SliceBuilder) AppendUint32Slice(value []uint32)

AppendUint32Slice appends a uint32 slice to this slice builder

func (*SliceBuilder) AppendUint32SliceDelta ΒΆ

func (s *SliceBuilder) AppendUint32SliceDelta(value []uint32)

AppendUint32SliceDelta appends a uint32 slice using delta encoding

func (*SliceBuilder) AppendUint64Slice ΒΆ

func (s *SliceBuilder) AppendUint64Slice(value []uint64)

AppendUint64Slice appends a uint64 slice to this slice builder

func (*SliceBuilder) AppendUint64SliceDelta ΒΆ

func (s *SliceBuilder) AppendUint64SliceDelta(value []uint64)

AppendUint64SliceDelta appends a uint64 slice using delta encoding

func (*SliceBuilder) AppendUintSlice ΒΆ

func (s *SliceBuilder) AppendUintSlice(value []uint)

AppendUintSlice appends a uint slice to this slice builder

func (*SliceBuilder) AppendUintSliceDelta ΒΆ

func (s *SliceBuilder) AppendUintSliceDelta(value []uint)

AppendUintSliceDelta appends a uint slice using delta encoding

type SliceEncoder ΒΆ

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

func NewSliceEncoder ΒΆ

func NewSliceEncoder(t any) *SliceEncoder

func NewSliceEncoderUsingTag ΒΆ

func NewSliceEncoderUsingTag(t any, usingTagName string) *SliceEncoder

func NewSliceEncoderUsingTagWithSchema ΒΆ

func NewSliceEncoderUsingTagWithSchema(t any, usingTagName string, sc *Buffer) *SliceEncoder

NewSliceEncoderUsingTagWithSchema allows us to create an instruction which can iterate over a slice of different data types at runtime

func (*SliceEncoder) ClearSchema ΒΆ

func (s *SliceEncoder) ClearSchema()

ClearSchema removes all data from the schema of this instance

func (*SliceEncoder) Marshal ΒΆ

func (s *SliceEncoder) Marshal(v any, w *Buffer)

Marshal executes the instruction set built up by NewSliceEncoder

func (*SliceEncoder) Schema ΒΆ

func (s *SliceEncoder) Schema() *Buffer

Schema returns the schema without any header information

type TrustHeader ΒΆ

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

TrustHeader enables HTTP-based trusted schema mode. Implements the KVP interface for HTTP headers.

func NewTrustHeader ΒΆ

func NewTrustHeader(d *decoderImpl) TrustHeader

NewTrustHeader creates an HTTP header for schema trust negotiation. Use with NewBufferWithTrust to skip schema transmission when both sides have matching schemas.

func (TrustHeader) Key ΒΆ

func (t TrustHeader) Key() string

Key provides the header name

func (TrustHeader) Value ΒΆ

func (t TrustHeader) Value() string

Value provides the header content

type Trustee ΒΆ

type Trustee interface {
	Hash() uint32
}

Trustee interface enables schema trust verification. HTTPTrustee provides a default HTTP-based implementation.

func HTTPTrustee ΒΆ

func HTTPTrustee(r *http.Request) Trustee

HTTPTrustee implements trust verification via the X-Glint-Trust HTTP header. Use with NewBufferWithTrust to enable schema omission for trusted requests.

type Visitor ΒΆ

type Visitor interface {
	VisitFlags(flags byte) error
	VisitSchemaHash(hash []byte) error
	VisitField(name string, wire WireType, body Reader) (Reader, error)
	VisitArrayStart(name string, wire WireType, length int) error
	VisitArrayEnd(name string) error
	VisitStructStart(name string) error
	VisitStructEnd(name string) error
}

Visitor is an interface that can be implemented to walk a document

type Walker ΒΆ

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

Walker walks a document

func NewWalker ΒΆ

func NewWalker(doc []byte) Walker

NewWalker creates a new walker

func (*Walker) Walk ΒΆ

func (w *Walker) Walk(visitor Visitor) error

Walk walks the document

type WireType ΒΆ

type WireType uint
const (
	WireBool    WireType = 1
	WireInt     WireType = 2
	WireInt8    WireType = 3
	WireInt16   WireType = 4
	WireInt32   WireType = 5
	WireInt64   WireType = 6
	WireUint    WireType = 7
	WireUint8   WireType = 8
	WireUint16  WireType = 9
	WireUint32  WireType = 10
	WireUint64  WireType = 11
	WireFloat32 WireType = 12
	WireFloat64 WireType = 13
	WireString  WireType = 14
	WireBytes   WireType = 15
	WireStruct  WireType = 16
	WireMap     WireType = 17
	WireTime    WireType = 18
	// maximum value 31 (5-bit limit)
	WireTypeMask = 0b00011111

	WireSliceFlag WireType = 1 << 5 // marks slice fields
	WirePtrFlag   WireType = 1 << 6 // marks nullable fields
	WireDeltaFlag WireType = 1 << 7 // delta encoding for numeric slices

)

func ReflectKindToWireType ΒΆ

func ReflectKindToWireType(k reflect.Type) WireType

ReflectKindToWireType converts Go reflection types to glint wire types

func (WireType) String ΒΆ

func (w WireType) String() string

Directories ΒΆ

Path Synopsis
cmd
glint command

Jump to

Keyboard shortcuts

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