- Go 99.1%
- Nix 0.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
instead of doing that at the parse level, i moved some logic to the scanner. maybe not very good and should be done in one place instead, but okay for now. two biggest changes for QoL: 1. errors specify both the start and the end 2. some errors include a hint with the first point they are now less confusing, because it was showing the start of the token. with the second point it's probably going to be more clear that a document is expected to be a v2, because hint tells to "use a hash". that is a breaking change, because i removed ParseError (not confident it is even needed right now). may be, once again, reconsidered later, but only when i am going to be sure that is a good design |
||
| testdata | ||
| .gitignore | ||
| arshal_test.go | ||
| compress.go | ||
| debug.go | ||
| example_test.go | ||
| flake.lock | ||
| flake.nix | ||
| format.go | ||
| go.mod | ||
| is.go | ||
| justfile | ||
| kdly_test.go | ||
| LICENSE | ||
| marshal.go | ||
| node.go | ||
| node_test.go | ||
| number.go | ||
| parse.go | ||
| parse_test.go | ||
| read.go | ||
| README.md | ||
| reflect.go | ||
| scan.go | ||
| scan_test.go | ||
| string.go | ||
| string_test.go | ||
| token.go | ||
| treefmt.nix | ||
| unmarshal.go | ||
| value.go | ||
| write.go | ||
kdly
kdly is a Go library for KDL 2.0.0. It does not support KDL v1 in any way. If you need an implementation for 1.0.0, please see other implementations.
Features
- Strict KDL v2 compliance with no v1 support and without any extensions.
- Open and simple design focused on fully exported parse tree structures.
- Format- and comment-preserving scanner/parser.
- Formatting (WIP)
- Compressing (WIP)
- (Un)marshaling (WIP)
The library requires at least Go 1.27 and has no module dependencies.
Credits
While no code was taken directly, first revisions of this library were heavily inspired from kdl-go by sblinch on GitHub. Also, many architectural decisions are influenced by the standard library (GitHub), as well as some implementation details.
License
Files in the testdata folder are taken from the official KDL test suite. They are distributed under CC BY-SA 4.0 license.
Source code in this project is distributed under BSD-3-Clause license.
Issues
The project is still in 'alpha'. API is not stable and there are not enough tests to guarantee that all features work correctly. However, most design decisions are unlikely to change.
There are some issues, limitations and other known things about the project that don't work as expected.
-
Some multi-line comment sequences are not recognized properly. For example,
/*/*/. -
Single- and multi-line comments are recognized as separate tokens with their own contents. However, slashdashes are recognized as a simple
/-sequence. The parser allows any combinations of tokens in slashdashed elements, but these tokens should be well-formed. This means, that if a slashdashed element has, for example, an invalid string, then the parse won't succeed. -
Formatting is not properly tested, so use it with caution on real documents.
-
(Un)marshaling is not properly tested and is in the state of a rewrite.
Compatibility
While the library is not stable yet (no major version or it is zero), breaking changes can be done without prior notice. Please be careful when using and updating the library at this stage.
However, the project is already able to give some non-formal compatibility guarantees even in this state:
-
The behavior listed in the issues should not be depended upon: it's either non-final or is a bug. That is also the case for undocumented (un)marshaling behavior.
-
Parse tree types (
Document,Nodeand other types used in them) are not expected to be changed any time soon. However, some functions or methods related to them (to be precise,NewDocument(),Document.Bind()andVersion()) may be changed. -
Logic for converting
NumberorStringtypes to other types is guaranteed only in terms of KDL specification. For example, conversion of aNumberto a Go primitive right now is done viastrconv, and can be more forgiving than the permitted KDL syntax. The underlying implementation can be changed to remove this behavior.
Documentation
While KDL looks very similar to JSON, it is a node-based language like XML. Therefore, in KDL, two nodes on a single level with the same name are allowed, and their order matters.
As said in encoding/xml, these
types of data collections cannot be represented easily in Go. Structs are single
key-value pairs, and while order of the fields is impotant, most of the time it
is unused.
Because of that, the library provides a first-class support for it's own data
types like Document and Node, which are able to represent any valid KDL
document byte-by-byte. These types are fully public and used almost everywhere.
(Un)marshaling is also supported, but uses it's own set of rules and the
aforementioned Document type. If you need more manual control, then please use
the types directly instead.
Quickstart
A single KDL document is mapped to a single Document struct. A KDL document is
a whole file or data stream until EOF. To either parse or format a single
document, use the Parser and Formatter types:
// error and file handling removed for brevity
f, err := os.Open("input.kdl")
doc, err := kdly.NewParser(f).Parse()
// do anything you want to 'doc'
doc.Nodes = append(kdly.Version(), doc.Nodes...)
f, err = os.Open("output.kdl")
err = kdly.NewFormatter(f).Format(doc)
If you need to work with freeform Go values, then use (un)marshaling via
NewDocument() and Document.Bind():
type Config struct {
Version int `kdly:"version"`
}
cfg := Config{Version: 1}
doc, err := kdly.NewDocument(cfg)
f, err := os.Open("config.kdl")
err = kdly.NewFormatter(f).Format(doc) // version 1
cfg = Config{}
f, err = os.Open("config.kdl")
doc, err = kdly.NewParser(f).Parse()
err = doc.Bind(&cfg) // cfg.Version = 1