# interpres A TOML 1.0 and 1.1 parser and encoder for Go, written with the standard library alone. `interpres` (Latin for *interpreter*) gives zero-dependency programs an `encoding/json`-style API for reading and writing TOML, and passes the entire official [toml-test](https://github.com/toml-lang/toml-test) suite: 214 valid and 467 invalid cases, zero failures. ## Features - **Full TOML 1.0 and 1.1**: bare, quoted and dotted keys; tables and arrays of tables; basic and literal strings including multiline, with the 1.1 `\e` and `\xHH` escapes; integers in the four radixes with `_` separators; floats with exponents, `inf` and `nan`; booleans; the four date-time kinds, seconds optional as of 1.1; arrays and inline tables, multi-line as of 1.1. - **Decoding and encoding**: `Parse` for an untyped tree, `Unmarshal` and `Marshal` for structs and maps, mirroring `encoding/json`. - **Strict decoding**: `NewDecoder().DisallowUnknownFields()` rejects keys that match no destination field, at every struct depth. - **Custom types**: `Marshaler` and `Unmarshaler` let a type control its own TOML representation in both directions. - **Cancellation**: every entry point has a `*Context` sibling that honours a `context.Context`. - **Configurable emission**: `Encoder` options for declaration-order output, omitting empty arrays, and literal multiline strings. ## Install As a library: ```sh go get sourcedock.dev/petrbalvin/interpres/v2 ``` Requires Go 1.27.1 or newer. The module imports only the standard library. ## Quick start ```sh git clone https://sourcedock.dev/petrbalvin/interpres.git cd interpres just example ``` `just example` runs the tour in `examples/basic`: it decodes an embedded document into a struct, prints it, and re-encodes it under both `Encoder` layouts. ## Usage ### Decode into a struct ```go type Config struct { Title string `toml:"title"` Server struct { Host string `toml:"host"` Port int `toml:"port"` } `toml:"server"` } var cfg Config err := interpres.Unmarshal(data, &cfg) ``` Fields match by the `toml:"name"` tag, or by the lower-cased field name when no tag is present; `toml:"-"` skips a field. `Parse` returns the untyped `map[string]any` tree instead, and `UnmarshalContext` accepts a context. ### Encode from a struct ```go out, err := interpres.Marshal(cfg) ``` writes: ```toml title = "example" [server] host = "127.0.0.1" port = 9090 ``` Tables are laid out scalars first, then sub-tables, then arrays of tables, which is the layout that re-parses to the same tree. ### Strict decoding ```go err := interpres.NewDecoder(). DisallowUnknownFields(). Decode(data, &cfg) ``` A key with no matching field becomes an error instead of a silent drop. ### Custom types ```go type Port int func (p Port) MarshalTOML() (any, error) { return int64(p), nil } type IP struct{ net.IP } func (ip *IP) UnmarshalTOML(data any) error { s, ok := data.(string) if !ok { return fmt.Errorf("ip: not a string") } ip.IP = net.ParseIP(s) return nil } ``` The value `MarshalTOML` returns is encoded in place of the receiver; `UnmarshalTOML` receives the parsed value verbatim. ### Encoder options ```go out, err := interpres.NewEncoder(). GroupByKind(false). // preserve declaration order OmitEmptyArrays(). // skip empty scalar arrays UseLiteralMultiline(80). // long multi-line strings as literal blocks Marshal(cfg) ``` ### Cancellation ```go ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() out, err := interpres.MarshalContext(ctx, cfg) ``` `ParseContext`, `UnmarshalContext`, `(*Decoder).DecodeContext` and `(*Encoder).MarshalContext` follow the same pattern. The full rules for field matching, numeric conversion and emission live in [docs/API.md](docs/API.md). ## Development ```sh just build # compile bin/interpres-decode just test # the suite, with the 80 percent coverage floor just toml-test # the official compliance suite, needs toml-test on PATH just fmt # gofmt in place ``` See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for the full workflow, and [CONTRIBUTING.md](CONTRIBUTING.md) for how to contribute. ## Documentation - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): components and data flow - [docs/API.md](docs/API.md): the API reference, decoding and encoding rules - [docs/CLI.md](docs/CLI.md): the interpres-decode toml-test adapter and validator ## Licence MIT. See [LICENSE](LICENSE). Copyright © 2026 [Petr Balvín](https://petrbalvin.org)