vdf

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 16 Imported by: 0

README

vdf

This project provides a high performance implementation of Valve Data Format (VDF) text and binary formats.
It is built around io.Reader and io.Writer for streaming workloads, keeps an explicit AST (Document and Node) as the canonical model, preserves node order and duplicate keys, and includes low allocation byte slice encode paths.

Full API reference: https://pkg.go.dev/github.com/woozymasta/vdf

Install

go get github.com/woozymasta/vdf

Reading VDF

Use ParseString, ParseBytes, or NewDecoder depending on your input source.

doc, err := vdf.ParseString(`"root" { "name" "srv" }`)
if err != nil {
    return err
}

root := doc.Roots[0]
name := root.First("name")

Use auto format detection when input may be text or binary:

doc, err := vdf.ParseAuto(data)
if err != nil {
    return err
}

For file inputs, use ParseFile with optional options or convenience wrappers: ParseTextFile and ParseAutoFile.

Writing VDF

For full document encode, use WriteString, AppendText, AppendBinary, or NewEncoder.

out, err := vdf.WriteString(doc)
if err != nil {
    return err
}

For binary output with low allocations:

bin, err := vdf.AppendBinary(nil, doc, vdf.EncodeOptions{
    Format: vdf.FormatBinary,
})
if err != nil {
    return err
}

If strict AST checks are required before encoding:

enc := vdf.NewEncoder(w, vdf.EncodeOptions{
    Format:   vdf.FormatText,
    Validate: true,
})
err := enc.EncodeDocument(doc)

For file output, use WriteFile with optional options or convenience wrappers: WriteTextFile and WriteBinaryFile.

Building a VDF document

Fluent Builder

NewBuilder provides a safe, ordered API for constructing documents:

doc, err := vdf.NewBuilder("settings").
    Set("name", "demo").
    SetUint32("port", 2302).
    Object("auth", func(b *vdf.Builder) {
        b.Set("token", "abc123")
    }).
    Document()
Manual construction
doc := vdf.NewDocumentWithFormat(vdf.FormatText)
root := vdf.NewObjectNode("settings")
root.Add(vdf.NewStringNode("name", "demo"))
root.Add(vdf.NewUint32Node("port", 2302))
doc.AddRoot(root)

NodeObject keeps ordered children and allows duplicate keys. This matches real VDF behavior.

Reflection API

Use Marshal and Unmarshal to convert between Go structs and VDF documents.

type Server struct {
    Name string `vdf:"name"`
    Port uint32 `vdf:"port"`
}

// Encode
doc, err := vdf.Marshal("Server", Server{Name: "game-1", Port: 2302})

// Decode
var s Server
err = vdf.Unmarshal(doc, "Server", &s)
Struct tags
Tag Meaning
vdf:"name" Use name as the VDF key
vdf:"-" Skip this field
vdf:",omitempty" Omit if reflect.Value.IsZero() is true
vdf:",omitzero" Omit if IsZero() bool is true, else reflect zero check
vdf:",inline" Hoist struct fields into the parent object
vdf:",repeated" Map []T to multiple sibling nodes with the same key
vdf:",indexed" Map []T to a child object with keys "0", "1", ...

Fields implementing encoding.TextMarshaler / TextUnmarshaler are handled automatically.

Streaming traversal

Two event-based APIs are available.
Both return events of type EventType: EventDocumentStart, EventObjectStart, EventObjectEnd, EventString, EventUint32, EventDocumentEnd.

WalkEvents - AST-based traversal

Decodes the full document into an AST on the first call, then traverses it in DFS order. Use when you need the parsed document available after iteration.

dec := vdf.NewDecoder(r, vdf.DecodeOptions{Format: vdf.FormatAuto})
for {
    ev, err := dec.WalkEvents()
    if err != nil {
        break
    }
    _ = ev
}
NextEvent - true streaming

Yields events directly from the reader without building an AST. Suitable for large inputs where keeping the full document in memory is undesirable.

dec := vdf.NewDecoder(r, vdf.DecodeOptions{Format: vdf.FormatAuto})
for {
    ev, err := dec.NextEvent()
    if err != nil {
        break
    }
    _ = ev
}

WalkEvents and NextEvent are mutually exclusive on the same Decoder instance. Mixing them returns ErrInvalidNodeState.

Security limits

Use DecodeOptions to cap memory usage when parsing untrusted input:

doc, err := vdf.ParseBytes(data, vdf.DecodeOptions{
    Format:         vdf.FormatAuto,
    MaxDepth:       32,
    MaxNodes:       10_000,
    MaxStringBytes: 4096, // ceiling for both keys and values
    MaxKeyBytes:    256,  // per-key limit (overrides MaxStringBytes keys)
    MaxValueBytes:  4096, // per-value limit (overrides MaxStringBytes values)
})

All limits use 0 to mean unlimited (the default).

Compatibility notes

  • Text format - keys and values may be quoted or unquoted. Escape sequences \\, \", \n, \t, \r are supported. Line comments (// ...) are supported; block comments (/* ... */) are not.
  • Binary format - little-endian uint32, null-terminated C strings. Type bytes:
    • 0x00 object start
    • 0x01 string
    • 0x02 uint32
    • 0x08 object end
  • Auto-detection - FormatAuto peeks up to 64 bytes to detect the format. Files shorter than 64 bytes are handled correctly.
  • Duplicate keys - the AST preserves duplicate keys in source order. Use Node.All(key) to retrieve all matches. Strict: true rejects duplicates at parse time.
  • Map conversions:
    • ToMapLossy applies last-write-wins for duplicate keys;
    • ToMapStrict returns an error.
    • FromMapSorted builds a document with lexicographically ordered keys for deterministic output.

Documentation

Overview

Package vdf implements a parser and encoder for Valve Data Format (VDF) in text and binary variants.

Data model

The canonical model is an AST:

  • Document is a full file with ordered root nodes.
  • NodeObject keeps ordered children and allows duplicate keys.
  • NodeString and NodeUint32 are scalar leaves.

This preserves VDF semantics that are commonly lost in map-based APIs (ordering and duplicate keys).

Decode API

Use Decoder for stream-oriented decoding from io.Reader:

dec := vdf.NewDecoder(r, vdf.DecodeOptions{Format: vdf.FormatAuto})
doc, err := dec.DecodeDocument()

For byte slices and strings use ParseBytes and ParseString. For file paths use ParseFile with optional DecodeOptions, or ParseTextFile/ParseAutoFile.

WalkEvents decodes the full document into an AST on the first call, then returns DFS traversal events on subsequent calls. Use it when you need the document available after iteration:

event, err := dec.WalkEvents()

NextEvent is a true streaming decoder: it reads and yields events one at a time without building an AST, making it suitable for large inputs. WalkEvents and NextEvent are mutually exclusive on a single Decoder instance.

Security limits

DecodeOptions.MaxDepth and MaxNodes bound recursion and node count. MaxKeyBytes, MaxValueBytes, and MaxStringBytes bound string lengths for keys and values respectively. All limits use 0 to mean unlimited.

Encode API

Use Encoder for stream-oriented output to io.Writer:

enc := vdf.NewEncoder(w, vdf.EncodeOptions{Format: vdf.FormatText})
err := enc.EncodeDocument(doc)

Manual streaming methods are available for incremental writing: StartObject, WriteString, WriteUint32, EndObject, Close. For file output use WriteFile with optional EncodeOptions, or WriteTextFile/WriteBinaryFile.

Fast paths

AppendText and AppendBinary append encoded output directly into destination byte slices to reduce allocations on hot paths.

Builder

NewBuilder provides a fluent, ordered API for constructing Documents without manual AST manipulation:

doc, err := vdf.NewBuilder("root").
	Set("key", "value").
	Object("child", func(b *vdf.Builder) { b.SetUint32("n", 1) }).
	Document()

Reflection API

Marshal and Unmarshal convert between Go structs and VDF Documents using struct field tags of the form vdf:"name,option":

type S struct {
	Name string `vdf:"name"`
	Port uint32 `vdf:"port"`
}
doc, _ := vdf.Marshal("Server", S{Name: "x", Port: 2302})
var s S
_ = vdf.Unmarshal(doc, "Server", &s)

Supported options: omitempty, inline, repeated, indexed. Fields implementing encoding.TextMarshaler/TextUnmarshaler are handled automatically.

Validation

Document.Validate can be called explicitly when strict AST checks are required. For performance, encoding does not force full validation unless EncodeOptions.Validate is set to true.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidFormat indicates unsupported format selection.
	ErrInvalidFormat = errors.New("invalid VDF format")
	// ErrUnrecognizedType indicates that an unknown binary VDF type byte was encountered.
	ErrUnrecognizedType = errors.New("unrecognized VDF type")
	// ErrBufferOverflow indicates that parsing attempted to read past available input bytes.
	ErrBufferOverflow = errors.New("buffer overflow")
	// ErrNullInString indicates that a binary VDF string contains an embedded null byte.
	ErrNullInString = errors.New("null byte found in string")
	// ErrUnsupportedMapValueType indicates that map conversion encountered an unsupported value type.
	ErrUnsupportedMapValueType = errors.New("unsupported map value type")
	// ErrIntOutOfRange indicates an integer cannot be represented as uint32.
	ErrIntOutOfRange = errors.New("integer out of uint32 range")
	// ErrDuplicateKeyInStrictMode indicates strict map conversion encountered duplicate keys.
	ErrDuplicateKeyInStrictMode = errors.New("duplicate key in strict map conversion")
	// ErrInvalidNodeState indicates AST node fields do not match node kind invariants.
	ErrInvalidNodeState = errors.New("invalid node state")
	// ErrDepthLimitExceeded indicates decode exceeded configured max depth.
	ErrDepthLimitExceeded = errors.New("maximum depth exceeded")
	// ErrNodeLimitExceeded indicates decode exceeded configured max node count.
	ErrNodeLimitExceeded = errors.New("maximum node count exceeded")
	// ErrUnexpectedEOFInQuotedString indicates that a quoted text token ended before its closing quote.
	ErrUnexpectedEOFInQuotedString = errors.New("unexpected EOF in quoted string")
	// ErrUnexpectedEOFInEscapeSequence indicates that an escape sequence ended before its escaped rune.
	ErrUnexpectedEOFInEscapeSequence = errors.New("unexpected EOF in escape sequence")
	// ErrUnexpectedCharacter indicates that the lexer found an invalid token start.
	ErrUnexpectedCharacter = errors.New("unexpected character")
	// ErrExpectedStringKey indicates that the parser expected a string token for a node key.
	ErrExpectedStringKey = errors.New("expected string key")
	// ErrExpectedValueOrObject indicates that the parser expected either a string value or an object start.
	ErrExpectedValueOrObject = errors.New("expected value or '{'")
	// ErrExpectedObjectStart indicates that the parser expected an opening object brace.
	ErrExpectedObjectStart = errors.New("expected '{'")
	// ErrUnexpectedEOFInObject indicates that the parser reached EOF before closing an object.
	ErrUnexpectedEOFInObject = errors.New("unexpected EOF, expected '}'")
	// ErrKeyTooLong indicates that a parsed key exceeded the configured byte limit.
	ErrKeyTooLong = errors.New("key exceeds maximum byte length")
	// ErrValueTooLong indicates that a parsed string value exceeded the configured byte limit.
	ErrValueTooLong = errors.New("string value exceeds maximum byte length")
	// ErrReflectUnsupportedType indicates that a Go type cannot be mapped to a VDF node.
	ErrReflectUnsupportedType = errors.New("unsupported Go type for VDF reflection")
	// ErrReflectFieldMismatch indicates a type mismatch or missing key during Unmarshal.
	ErrReflectFieldMismatch = errors.New("VDF field mismatch during unmarshal")
)

Functions

func AppendBinary

func AppendBinary(dst []byte, doc *Document, opts EncodeOptions) ([]byte, error)

AppendBinary appends binary VDF output to destination byte slice.

func AppendText

func AppendText(dst []byte, doc *Document, opts EncodeOptions) ([]byte, error)

AppendText appends text VDF output to destination byte slice.

func Unmarshal added in v0.2.0

func Unmarshal(doc *Document, root string, out any) error

Unmarshal decodes the named root object from doc into the struct pointed to by out. out must be a non-nil pointer to a struct.

Example
package main

import (
	"fmt"

	"github.com/woozymasta/vdf"
)

func main() {
	type Server struct {
		Name string `vdf:"name"`
		Port uint32 `vdf:"port"`
	}

	doc, _ := vdf.ParseString(`"Server" { "name" "game-1" "port" "2302" }`)

	var s Server
	if err := vdf.Unmarshal(doc, "Server", &s); err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(s.Name)
	fmt.Println(s.Port)

}
Output:
game-1
2302

func Write

func Write(w io.Writer, doc *Document) error

Write encodes document as text VDF with default options.

func WriteBinaryFile

func WriteBinaryFile(path string, doc *Document) error

WriteBinaryFile encodes document as binary VDF file.

func WriteFile

func WriteFile(path string, doc *Document, opts ...EncodeOptions) (err error)

WriteFile encodes document to file. Without options it writes text format.

func WriteString

func WriteString(doc *Document) (string, error)

WriteString encodes document as text VDF string.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/woozymasta/vdf"
)

func main() {
	doc := vdf.NewDocumentWithFormat(vdf.FormatText)
	root := vdf.NewObjectNode("app")
	root.Add(vdf.NewStringNode("name", "demo"))
	root.Add(vdf.NewUint32Node("id", 7))
	doc.AddRoot(root)

	text, err := vdf.WriteString(doc)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(strings.Contains(text, `"app"`))
	fmt.Println(strings.Contains(text, `"id"`))

}
Output:
true
true

func WriteTextFile

func WriteTextFile(path string, doc *Document) error

WriteTextFile encodes document as text VDF file.

Types

type Builder added in v0.2.0

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

Builder constructs a VDF Document using a fluent API. Methods return the receiver so calls can be chained. The first error encountered is stored and silently skips subsequent calls; Document returns it at finalization.

func NewBuilder added in v0.2.0

func NewBuilder(rootKey string) *Builder

NewBuilder creates a Builder with a single root object node.

Example
package main

import (
	"fmt"

	"github.com/woozymasta/vdf"
)

func main() {
	doc, err := vdf.NewBuilder("config").
		Set("name", "server").
		SetUint32("port", 2302).
		Object("db", func(b *vdf.Builder) {
			b.Set("host", "localhost")
		}).
		Document()
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(doc.Roots[0].Key)
	fmt.Println(*doc.Roots[0].First("name").StringValue)

}
Output:
config
server

func (*Builder) Document added in v0.2.0

func (b *Builder) Document() (*Document, error)

Document finalizes the builder and returns the completed Document. Returns an error if any call previously failed or if unclosed objects remain. After a successful call, the builder is considered finalized; further calls return an error.

func (*Builder) Object added in v0.2.0

func (b *Builder) Object(key string, fn func(*Builder)) *Builder

Object opens a nested object scope, invokes fn within it, then closes it.

func (*Builder) Set added in v0.2.0

func (b *Builder) Set(key, value string) *Builder

Set adds a string key/value node to the current object.

func (*Builder) SetUint32 added in v0.2.0

func (b *Builder) SetUint32(key string, value uint32) *Builder

SetUint32 adds a uint32 key/value node to the current object.

type DecodeOptions

type DecodeOptions struct {
	// MaxDepth limits nested object depth (0 means unlimited).
	MaxDepth int
	// MaxNodes limits total parsed nodes (0 means unlimited).
	MaxNodes int
	// MaxKeyBytes limits the byte length of any parsed key (0 means unlimited).
	MaxKeyBytes int
	// MaxValueBytes limits the byte length of any parsed string value (0 means unlimited).
	MaxValueBytes int
	// MaxStringBytes is a convenience ceiling applied to both keys and values
	// when their specific limit is zero (0 means unlimited).
	MaxStringBytes int
	// Format selects expected input format.
	Format Format
	// Strict enables stricter validation paths where available.
	Strict bool
}

DecodeOptions controls decoder behavior.

type Decoder

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

Decoder decodes VDF data from an input stream.

func NewDecoder

func NewDecoder(r io.Reader, opts DecodeOptions) *Decoder

NewDecoder creates a decoder with normalized options.

func (*Decoder) DecodeDocument

func (d *Decoder) DecodeDocument() (*Document, error)

DecodeDocument decodes the full input stream into a document.

func (*Decoder) NextEvent

func (d *Decoder) NextEvent() (Event, error)

NextEvent returns the next event from the input stream without building an AST. On the first call it initialises a streaming reader; subsequent calls continue from that position. Returns io.EOF when all events have been consumed.

NextEvent is a true streaming decoder: it reads and yields events one at a time with no intermediate AST, making it suitable for large inputs or constrained memory environments. The decoded document is not available after iteration; use WalkEvents when post-iteration document access is required.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/woozymasta/vdf"
)

func main() {
	dec := vdf.NewDecoder(strings.NewReader(`"root" { "k" "v" }`), vdf.DecodeOptions{
		Format: vdf.FormatText,
	})

	count := 0
	for {
		_, err := dec.NextEvent()
		if err != nil {
			break
		}

		count++
	}

	fmt.Println(count)

}
Output:
5

func (*Decoder) WalkEvents added in v0.2.0

func (d *Decoder) WalkEvents() (Event, error)

WalkEvents returns the next DFS traversal event for the decoded document. The full document is decoded into an AST on the first call; subsequent calls traverse that AST in depth-first order. Returns io.EOF when all events have been emitted.

Use WalkEvents when you need the full document available for further access after iteration. For a one-pass, lower-memory alternative see NextEvent.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/woozymasta/vdf"
)

func main() {
	dec := vdf.NewDecoder(strings.NewReader(`"root" { "k" "v" }`), vdf.DecodeOptions{
		Format: vdf.FormatText,
	})

	count := 0
	for {
		_, err := dec.WalkEvents()
		if err != nil {
			break
		}

		count++
	}

	fmt.Println(count)

}
Output:
5

type Document

type Document struct {
	// Roots contains top-level nodes in source order.
	Roots []*Node `json:"roots,omitempty" yaml:"roots,omitempty"`
	// Format is the source or intended encode format.
	Format Format `json:"format,omitempty" yaml:"format,omitempty"`
}

Document represents a complete VDF document.

func FromMap

func FromMap(rootKey string, m Map) (*Document, error)

FromMap builds a document with one object root from a map.

func FromMapSorted added in v0.2.0

func FromMapSorted(rootKey string, m Map) (*Document, error)

FromMapSorted builds a document with one object root from a map with keys sorted. Unlike FromMap, key iteration order is deterministic (lexicographic).

func Marshal added in v0.2.0

func Marshal(root string, v any) (*Document, error)

Marshal encodes a Go struct into a Document with one root object node. v must be a struct or a pointer to a struct.

Example
package main

import (
	"fmt"

	"github.com/woozymasta/vdf"
)

func main() {
	type Server struct {
		Name string `vdf:"name"`
		Port uint32 `vdf:"port"`
	}

	doc, err := vdf.Marshal("Server", Server{Name: "game-1", Port: 2302})
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(doc.Roots[0].Key)
	fmt.Println(*doc.Roots[0].First("name").StringValue)

}
Output:
Server
game-1

func NewDocument

func NewDocument() *Document

NewDocument creates an empty document with auto format marker.

func NewDocumentWithFormat

func NewDocumentWithFormat(format Format) *Document

NewDocumentWithFormat creates an empty document with explicit format marker.

func Parse

func Parse(r io.Reader) (*Document, error)

Parse decodes text VDF from reader.

func ParseAuto

func ParseAuto(data []byte) (*Document, error)

ParseAuto decodes VDF bytes with automatic format detection.

Example
package main

import (
	"fmt"

	"github.com/woozymasta/vdf"
)

func main() {
	doc, err := vdf.ParseAuto([]byte(`"cfg" { "timeout" "5" }`))
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(doc.Format == vdf.FormatText)

}
Output:
true

func ParseAutoFile

func ParseAutoFile(path string) (*Document, error)

ParseAutoFile decodes VDF file with automatic format detection.

func ParseBytes

func ParseBytes(data []byte, opts DecodeOptions) (*Document, error)

ParseBytes decodes VDF from bytes using the given options.

func ParseFile

func ParseFile(path string, opts ...DecodeOptions) (doc *Document, err error)

ParseFile decodes VDF from file path. Without options it decodes as text format.

func ParseString

func ParseString(s string) (*Document, error)

ParseString decodes text VDF from a string.

Example
package main

import (
	"fmt"

	"github.com/woozymasta/vdf"
)

func main() {
	doc, err := vdf.ParseString(`"root" { "name" "server-1" }`)
	if err != nil {
		fmt.Println(err)
		return
	}

	root := doc.Roots[0]
	fmt.Println(root.Key)
	fmt.Println(*root.First("name").StringValue)

}
Output:
root
server-1

func ParseTextFile

func ParseTextFile(path string) (*Document, error)

ParseTextFile decodes text VDF from file path.

func (*Document) AddRoot

func (d *Document) AddRoot(node *Node)

AddRoot appends a root node to the document.

func (*Document) ToMapLossy

func (d *Document) ToMapLossy() Map

ToMapLossy converts document to map using last-write-wins for duplicate keys.

func (*Document) ToMapStrict

func (d *Document) ToMapStrict() (Map, error)

ToMapStrict converts document to map and fails on duplicate keys.

func (*Document) Validate

func (d *Document) Validate() error

Validate ensures document and node invariants are satisfied.

type EncodeOptions

type EncodeOptions struct {
	// Indent sets one indentation level for text format.
	Indent string
	// Format selects output format.
	Format Format
	// Compact enables compact text encoding.
	Compact bool
	// Deterministic enables stable key ordering during encode.
	Deterministic bool
	// Validate enables full document validation before encoding.
	Validate bool
}

EncodeOptions controls encoder behavior.

type Encoder

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

Encoder encodes VDF documents to an output stream.

func NewEncoder

func NewEncoder(w io.Writer, opts EncodeOptions) *Encoder

NewEncoder creates a VDF encoder.

func (*Encoder) Close

func (e *Encoder) Close() error

Close finalizes manual streaming state.

func (*Encoder) EncodeDocument

func (e *Encoder) EncodeDocument(doc *Document) error

EncodeDocument encodes a complete document in selected output format.

func (*Encoder) EndObject

func (e *Encoder) EndObject() error

EndObject ends an object in manual streaming mode.

func (*Encoder) StartObject

func (e *Encoder) StartObject(key string) error

StartObject begins an object in manual streaming mode.

func (*Encoder) WriteString

func (e *Encoder) WriteString(key, value string) error

WriteString writes a string leaf in manual streaming mode.

func (*Encoder) WriteUint32

func (e *Encoder) WriteUint32(key string, value uint32) error

WriteUint32 writes an unsigned numeric leaf in manual streaming mode.

type Event

type Event struct {
	// StringValue is set for EventString.
	StringValue *string `json:"string_value,omitempty" yaml:"string_value,omitempty"`
	// Uint32Value is set for EventUint32.
	Uint32Value *uint32 `json:"uint32_value,omitempty" yaml:"uint32_value,omitempty"`
	// Key is the node key associated with this event.
	Key string `json:"key,omitempty" yaml:"key,omitempty"`
	// Depth is the traversal depth for this event.
	Depth int `json:"depth" yaml:"depth"`
	// Type is the event kind.
	Type EventType `json:"type" yaml:"type"`
}

Event is a streaming traversal event.

type EventType

type EventType uint8

EventType represents a decoded event type from streaming traversal.

const (
	// EventDocumentStart marks beginning of a document stream.
	EventDocumentStart EventType = iota + 1
	// EventDocumentEnd marks end of a document stream.
	EventDocumentEnd
	// EventObjectStart marks beginning of an object node.
	EventObjectStart
	// EventObjectEnd marks end of an object node.
	EventObjectEnd
	// EventString marks a string leaf node.
	EventString
	// EventUint32 marks a uint32 leaf node.
	EventUint32
)

type Format

type Format uint8

Format defines how encoded/decoded VDF data should be interpreted.

const (
	// FormatAuto enables format auto-detection for decoding.
	FormatAuto Format = iota
	// FormatText selects text VDF format.
	FormatText
	// FormatBinary selects binary VDF format.
	FormatBinary
)

type Map

type Map map[string]any

Map represents a generic key-value mapping used by explicit adapters. It is inherently lossy for duplicate keys and ordering.

type Node

type Node struct {
	// StringValue is set for NodeString.
	StringValue *string `json:"string_value,omitempty" yaml:"string_value,omitempty"`
	// Uint32Value is set for NodeUint32.
	Uint32Value *uint32 `json:"uint32_value,omitempty" yaml:"uint32_value,omitempty"`
	// Key is the node key.
	Key string `json:"key" yaml:"key"`
	// Children are set for NodeObject and preserve source order.
	Children []*Node `json:"children,omitempty" yaml:"children,omitempty"`
	// Kind defines the node payload shape.
	Kind NodeKind `json:"kind" yaml:"kind"`
}

Node represents a VDF AST node.

func NewObjectNode

func NewObjectNode(key string) *Node

NewObjectNode creates an object node with the provided key.

func NewStringNode

func NewStringNode(key, value string) *Node

NewStringNode creates a string node with the provided key and value.

func NewUint32Node

func NewUint32Node(key string, value uint32) *Node

NewUint32Node creates a uint32 node with the provided key and value.

func (*Node) Add

func (n *Node) Add(child *Node)

Add appends a child node to an object node.

func (*Node) All

func (n *Node) All(key string) []*Node

All returns all children with the given key in source order.

func (*Node) First

func (n *Node) First(key string) *Node

First returns the first child with the given key.

type NodeKind

type NodeKind uint8

NodeKind defines the value type represented by a node.

const (
	// NodeObject is a container node with ordered children.
	NodeObject NodeKind = iota + 1
	// NodeString is a leaf node containing a string value.
	NodeString
	// NodeUint32 is a leaf node containing an unsigned 32-bit value.
	NodeUint32
)

Jump to

Keyboard shortcuts

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