Skip to main content

Crate kahon

Crate kahon 

Source
Expand description

Streaming writer for the Kahon binary format - a JSON-shaped container with random-access B+tree arrays and objects.

Writer memory stays bounded by tree depth, not document size, so arbitrarily large documents stream through without buffering the whole thing.

§Quick start

use kahon::Writer;

let mut buf: Vec<u8> = Vec::new();

let mut monster = Writer::new(&mut buf).start_object();
monster.push_i64("hp", 80)?;
monster.push_bool("enraged", true)?;

{
    let mut weapons = monster.start_array("weapons")?;
    weapons.push_str("fist")?;

    let mut axe = weapons.start_object();
    axe.push_str("name", "great axe")?;
    axe.push_i64("damage", 15)?;
    // nested builders auto-close on drop
}

monster.end()?.finish()?;

§Building a document

A Writer holds exactly one root value: push a scalar, or open the root with start_array / start_object to get a RootArrayBuilder / RootObjectBuilder. Inside a container, ArrayBuilder / ObjectBuilder let you append more scalars and open nested containers. Object methods take the key positionally (obj.push_i64("hp", 80)); duplicate keys resolve last-wins.

Finish the document by calling .end() on the root builder, then .finish() on the writer it returns. The compiler enforces exactly-one-root and rejects finish before a root is written.

§Closing builders: Drop vs end

Nested ArrayBuilder / ObjectBuilder close on drop - handy on the happy path, but a close error has nowhere to go and poisons the writer instead. Call .end()? to surface that error as a Result.

Root builders (RootArrayBuilder, RootObjectBuilder) are #[must_use]: dropping one without .end() leaves the document without a trailer.

§Tuning the layout

use kahon::{BuildPolicy, Writer, WriterOptions};

let opts = WriterOptions {
    policy: BuildPolicy::disk_aligned(4096),
    ..Default::default()
};
let w = Writer::with_options(&mut sink, opts)?;

The default produces the tightest output and suits in-memory or network use. BuildPolicy::disk_aligned adds a small amount of padding for a layout friendlier to pread / mmap.

§Sinks

Any std::io::Write is a Sink - Vec<u8>, File, BufWriter, etc. all work without adapters.

§Errors

Fallible operations return WriteError. After any error mid- document, the writer is poisoned and further calls fail fast with WriteError::Poisoned instead of producing a malformed file.

Modules§

raw
Flat, runtime-checked writer surface for advanced integrations (FFI bridges, async stream parsers, storage adapters). Most users want Writer and its builders.

Structs§

ArrayBuilder
Handle for a nested array. Closes on drop; call .end()? instead to surface close errors as a Result.
BuildPolicy
How container nodes are sized and whether the body is page-aligned.
Empty
Typestate marker: writer has not yet received its root value. Exposes the push_* and start_* methods.
Filled
Typestate marker: writer’s root value is in place. Only finish is available.
ObjectBuilder
Handle for a nested object. Keys are passed positionally before their value. Closes on drop; call .end()? to surface close errors as a Result.
RootArrayBuilder
Root-level array builder. Returned by Writer::start_array. Call .end() to recover the Writer for finish - dropping without .end() leaves the document with no trailer.
RootObjectBuilder
Root-level object builder. Returned by Writer::start_object. Call .end() to recover the Writer for finish - dropping without .end() leaves the document with no trailer.
TrailerSnapshot
Closing bytes for a kahon document as it stands at a point in time.
Writer
Builder-pattern writer for a single Kahon document.
WriterOptions
Top-level writer configuration. Pass to Writer::with_options.

Enums§

NodeSizing
Strategy for choosing B+tree node size.
PageAlignment
Whether to pad the body for page-cache friendliness on disk.
WriteError
Errors returned by the writer.

Traits§

RewindableSink
A Sink that can discard bytes past a given length.
Sink
An append-only byte sink. Implemented for every io::Write via a blanket impl, so Vec<u8>, File, BufWriter, etc. work directly.

Type Aliases§

Result
Convenience alias for std::result::Result<T, WriteError>.