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.
NextEvent provides traversal events over the decoded document:
event, err := dec.NextEvent()
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.
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 ¶
- Variables
- func AppendBinary(dst []byte, doc *Document, opts EncodeOptions) ([]byte, error)
- func AppendText(dst []byte, doc *Document, opts EncodeOptions) ([]byte, error)
- func Write(w io.Writer, doc *Document) error
- func WriteBinaryFile(path string, doc *Document) error
- func WriteFile(path string, doc *Document, opts ...EncodeOptions) (err error)
- func WriteString(doc *Document) (string, error)
- func WriteTextFile(path string, doc *Document) error
- type DecodeOptions
- type Decoder
- type Document
- func FromMap(rootKey string, m Map) (*Document, error)
- func NewDocument() *Document
- func NewDocumentWithFormat(format Format) *Document
- func Parse(r io.Reader) (*Document, error)
- func ParseAuto(data []byte) (*Document, error)
- func ParseAutoFile(path string) (*Document, error)
- func ParseBytes(data []byte, opts DecodeOptions) (*Document, error)
- func ParseFile(path string, opts ...DecodeOptions) (doc *Document, err error)
- func ParseString(s string) (*Document, error)
- func ParseTextFile(path string) (*Document, error)
- type EncodeOptions
- type Encoder
- type Event
- type EventType
- type Format
- type Map
- type Node
- type NodeKind
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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 '}'") )
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 WriteBinaryFile ¶
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 ¶
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 ¶
WriteTextFile encodes document as text VDF file.
Types ¶
type DecodeOptions ¶
type DecodeOptions struct {
// Format selects expected input format.
Format Format
// Strict enables stricter validation paths where available.
Strict bool
// MaxDepth limits nested object depth (0 means unlimited).
MaxDepth int
// MaxNodes limits total parsed nodes (0 means unlimited).
MaxNodes int
}
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 ¶
DecodeDocument decodes the full input stream into a document.
func (*Decoder) NextEvent ¶
NextEvent returns the next DFS event for the decoded document.
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
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 NewDocument ¶
func NewDocument() *Document
NewDocument creates an empty document with auto format marker.
func NewDocumentWithFormat ¶
NewDocumentWithFormat creates an empty document with explicit format marker.
func ParseAuto ¶
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 ¶
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 ¶
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 ¶
ParseTextFile decodes text VDF from file path.
func (*Document) ToMapLossy ¶
ToMapLossy converts document to map using last-write-wins for duplicate keys.
func (*Document) ToMapStrict ¶
ToMapStrict converts document to map and fails on duplicate keys.
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) EncodeDocument ¶
EncodeDocument encodes a complete document in selected output format.
func (*Encoder) StartObject ¶
StartObject begins an object in manual streaming mode.
func (*Encoder) WriteString ¶
WriteString writes a string 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 Map ¶
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 ¶
NewObjectNode creates an object node with the provided key.
func NewStringNode ¶
NewStringNode creates a string node with the provided key and value.
func NewUint32Node ¶
NewUint32Node creates a uint32 node with the provided key and value.