ktav

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 11 Imported by: 0

README

ktav — Go bindings

Languages: English · Русский · 简体中文

Go bindings for the Ktav configuration format. Thin wrapper around the reference Rust parser, loaded at runtime through purego — so no cgo on the consumer side, standard go build just works.

go get github.com/ktav-lang/golang

Quick start

Parse — decode straight into a typed struct
package main

import (
    "fmt"

    ktav "github.com/ktav-lang/golang"
)

const src = `
service: web
port:i 8080
ratio:f 0.75
tls: true
tags: [
    prod
    eu-west-1
]
db.host: primary.internal
db.timeout:i 30
`

type Config struct {
    Service string   `json:"service"`
    Port    int64    `json:"port"`
    Ratio   float64  `json:"ratio"`
    TLS     bool     `json:"tls"`
    Tags    []string `json:"tags"`
    DB      struct {
        Host    string `json:"host"`
        Timeout int64  `json:"timeout"`
    } `json:"db"`
}

func main() {
    var cfg Config
    if err := ktav.LoadsInto(src, &cfg); err != nil {
        panic(err)
    }
    fmt.Printf("port=%d host=%s timeout=%ds\n",
        cfg.Port, cfg.DB.Host, cfg.DB.Timeout)
}
Walk — work with the dynamic shape, dispatch on type
dyn, _ := ktav.Loads(src)
for k, v := range dyn.(map[string]any) {
    switch x := v.(type) {
    case bool:           fmt.Printf("%s is bool=%v\n", k, x)
    case int64:          fmt.Printf("%s is int=%d\n", k, x)
    case float64:        fmt.Printf("%s is float=%g\n", k, x)
    case string:         fmt.Printf("%s is str=%q\n", k, x)
    case []any:          fmt.Printf("%s is array(%d)\n", k, len(x))
    case map[string]any: fmt.Printf("%s is object(%d)\n", k, len(x))
    case nil:            fmt.Printf("%s is null\n", k)
    }
}
Build & render — construct a document in code
doc := map[string]any{
    "name":  "frontend",
    "port":  int64(8443),
    "tls":   true,
    "ratio": 0.95,
    "upstreams": []any{
        map[string]any{"host": "a.example", "port": int64(1080)},
        map[string]any{"host": "b.example", "port": int64(1080)},
    },
    "notes": nil,
}
out, _ := ktav.Dumps(doc)
fmt.Print(out)
// name: frontend
// port:i 8443
// tls: true
// ratio:f 0.95
// upstreams: [
//     { host: a.example  port:i 1080 }
//     { host: b.example  port:i 1080 }
// ]
// notes: null

A complete runnable version lives in examples/basic.

API

Function Purpose
Loads(s string) (any, error) Parse a Ktav document into native Go values.
LoadsInto(s string, target any) error Parse into an arbitrary target (struct, map, …) via encoding/json.
Dumps(v any) (string, error) Render a Go value as Ktav text. Top-level must encode to an object.

Type mapping

Ktav Go
null nil
true / false bool
:i <digits> int64 if it fits, else *big.Int
:f <number> float64
bare scalar string
[ ... ] []any
{ ... } map[string]any (insertion order preserved)

On encode, Go int* / uint* / *big.Int become :i; float32 / float64 become :f; string stays a bare scalar. NaN and ±Inf are rejected. Structs are serialized through encoding/json first, so json:"..." tags are honoured.

How the native library is resolved

At first call the Go package resolves ktav_cabi in this order:

  1. $KTAV_LIB_PATH — absolute path to a local build. Most useful for development.
  2. User cache<os.UserCacheDir>/ktav-go/v<version>/…, downloaded on a previous call.
  3. GitHub Release download — the matching asset is fetched once from github.com/ktav-lang/golang/releases/download/v<version>/<name> and cached under (2). Requires network on first call after install.

Runtime support

  • Go 1.21+.
  • Prebuilt binaries for: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64, windows/arm64.
  • Linux distros must use glibc 2.17+ (Rust's default target). Alpine (musl) support is planned.

License

MIT — see LICENSE.

Ktav spec: ktav-lang/spec. Reference Rust crate: ktav-lang/rust.

Documentation

Overview

Package ktav is the Go binding for the Ktav configuration format.

The implementation loads a prebuilt `ktav_cabi` shared library via purego (no cgo required on the consumer side). On first call the library is downloaded from the matching GitHub Release and cached under the user cache directory; set $KTAV_LIB_PATH to point at a local build instead.

Type mapping

Loads/Dumps convert between Ktav values and Go values as follows:

Ktav              Go
─────────────── ───────────────────────────
null              nil
true / false      bool
:i <digits>       int64 if it fits, else *big.Int
:f <number>       float64
bare scalar       string
[ ... ]           []any
{ ... }           map[string]any (key order not preserved)

Key order from the source is **not** preserved on either side: decode returns a plain `map[string]any`, and encode goes through `encoding/json`, which emits object keys in alphabetical order. If you need a fixed shape, use `LoadsInto` into a struct.

On encode, Go *big.Int always emits `:i`; Go int / int64 / uint64 emit `:i`; Go float64 emits `:f`; Go string emits a bare scalar. NaN / ±Inf are rejected. Top-level value must encode to a Ktav object (i.e. a map[string]any or struct).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dumps

func Dumps(v any) (string, error)

Dumps renders a Go value as a Ktav document. The top-level must encode to a JSON object (map[string]any, struct, etc.).

func Loads

func Loads(src string) (any, error)

Loads parses a Ktav document and returns its Go representation (see package doc for the mapping).

func LoadsInto

func LoadsInto(src string, target any) error

LoadsInto parses a Ktav document and JSON-unmarshals the tagged intermediate into `target`. Handy for struct-typed configs:

var cfg MyConfig
_ = ktav.LoadsInto(src, &cfg)

`:i` scalars become JSON numbers or JSON strings (if they exceed json.Number precision); `:f` scalars become JSON numbers. Custom types wanting bigint precision should unmarshal into a json.Number field.

func NativeVersion

func NativeVersion() (string, error)

NativeVersion returns the version string baked into the loaded `ktav_cabi` shared library. Useful for diagnostics when a stale cache or KTAV_LIB_PATH points at an out-of-sync build.

Types

type Error

type Error struct{ Msg string }

Error is the binding's error type. Returned from every Loads / Dumps failure — both Rust-side parse/render errors and Go-side decode bugs (malformed tagged JSON, bad integer literal, etc.) — so callers can match all ktav failures with one `errors.As`.

func (*Error) Error

func (e *Error) Error() string

Directories

Path Synopsis
examples
basic command
End-to-end demo: parse a Ktav document into a typed struct, walk the dynamic shape, then build a fresh document in Go and render it back to Ktav text.
End-to-end demo: parse a Ktav document into a typed struct, walk the dynamic shape, then build a fresh document in Go and render it back to Ktav text.
internal
native
Package native resolves and dynamically loads the `ktav_cabi` shared library via purego.
Package native resolves and dynamically loads the `ktav_cabi` shared library via purego.

Jump to

Keyboard shortcuts

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