1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! 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.
//!
//! [Kahon binary format]: https://github.com/jankdc/kahon
//!
//! # Quick start
//!
//! ```
//! use kahon::Writer;
//!
//! # fn main() -> Result<(), kahon::WriteError> {
//! 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()?;
//! # Ok(())
//! # }
//! ```
//!
//! # Building a document
//!
//! A [`Writer`] holds exactly one root value: push a scalar, or open
//! the root with [`start_array`](Writer::start_array) /
//! [`start_object`](Writer::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()`](RootObjectBuilder::end) on
//! the root builder, then [`.finish()`](Writer::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};
//!
//! # fn main() -> Result<(), kahon::WriteError> {
//! # let mut sink: Vec<u8> = Vec::new();
//! let opts = WriterOptions {
//! policy: BuildPolicy::disk_aligned(4096),
//! ..Default::default()
//! };
//! let w = Writer::with_options(&mut sink, opts)?;
//! # let _ = w.push_null()?;
//! # Ok(())
//! # }
//! ```
//!
//! 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.
/// Flat, runtime-checked writer surface for advanced integrations
/// (FFI bridges, async stream parsers, storage adapters). Most users
/// want [`Writer`] and its builders.
pub use ;
pub use ;
pub use WriteError;
pub use ;
pub use TrailerSnapshot;
pub use ;
/// Convenience alias for `std::result::Result<T, WriteError>`.
pub type Result<T> = Result;