NAME

Text::KDL::XS - Fast KDL parser and emitter via libckdl

SYNOPSIS

use Text::KDL::XS qw(parse_kdl emit_kdl);

my $doc = parse_kdl(<<'KDL');
package "kdl-rs" {
    version "0.4.0"
    author "Kat Marchán" email="kat@example.com"
}
KDL

for my $node (@{ $doc->nodes }) {
    print $node->name, "\n";
}

my $kdl_text = emit_kdl($doc);

DESCRIPTION

Text::KDL::XS is a Perl XS binding to ckdl, a C11 library for reading and writing the KDL Document Language. Both KDL v1.0.0 and v2.0.0 are supported (auto-detected by default).

The module exposes two layers:

FUNCTIONS

parse_kdl( $source, %opts )

Parse a KDL document. $source may be one of:

  • a string (parsed in-memory)

  • an open file handle / IO object (read in chunks)

  • a code reference returning chunks of bytes (or undef/empty at EOF)

Options:

version => 'detect' | '1' | '2' (default 'detect')
emit_comments => 0 | 1 (default 0)

Returns a Text::KDL::XS::Document. Throws on malformed input.

emit_kdl( $tree, %opts )

Serialize a tree (or plain Perl data) to a KDL string. The emitter operates in one of two modes, chosen automatically from the input:

Tree mode (full fidelity)

Used when $tree is one of:

Tree mode preserves property order, type annotations, and the integer/float/bigint/string distinction on numbers.

Data mode (plain Perl convenience)

Used when $tree is any other HASH or ARRAY reference. The mapping is:

  • Hash ref - each key becomes a sibling node, in sorted-key order for deterministic output.

  • Array ref - each element becomes an anonymous node named - (the JSON-in-KDL convention).

  • Scalar / undef / boolean value - emitted as a single argument.

  • Empty array [] - emitted as a bare node with no args.

  • Array of scalars - emitted as multiple args of one node.

  • Hash ref value - emitted as a child block.

  • Array containing complex elements - repeated as sibling nodes, one per element.

Data mode is lossy: property order is sorted, and the array-vs-single-arg distinction does not round-trip exactly. Use tree mode when fidelity matters.

Scalar coercion

Argument and property values may be Text::KDL::XS::Value objects or plain Perl scalars. Plain scalars are coerced as follows:

undef                                  -> KDL null
JSON::PP::true / Types::Serialiser::*  -> KDL bool
integer-flagged SV                     -> KDL number (integer)
float-flagged SV                       -> KDL number (float)
any other scalar                       -> KDL string

Strings like "true" and "false" are not heuristically promoted to booleans - pass an explicit JSON::PP::true/JSON::PP::false if you need booleans. Other reference types in value position raise an error.

Options:

version => 'detect' | '1' | '2'
indent => $integer
escape_mode => $integer (see kdl_escape_mode in ckdl)
identifier_mode => $integer (see kdl_identifier_emission_mode)

Returns the emitted KDL string.

SEE ALSO

Text::KDL::XS::Parser, Text::KDL::XS::Document, Text::KDL::XS::Node, Text::KDL::XS::Value, Alien::ckdl, https://github.com/kdl-org/kdl, https://github.com/tjol/ckdl.

LICENSE

Copyright (C) Davenonymous.

This Perl distribution is licensed under the same terms as Perl itself. The bundled ckdl library (linked statically via Alien::ckdl) is MIT-licensed.