Skip to main content

tabnas_render/
lib.rs

1//! Renderers for the tabnas transducer protocols.
2//!
3//! A renderer decides how a semantic protocol becomes text: `TableRows/1`
4//! becomes CSV, `JsonEvents/1` becomes JSON, incrementally, through a
5//! coalescing writer with a byte budget. Source interpretation never
6//! crosses into this crate: a renderer sees labels and cells, never paths.
7//!
8//! - [`text`]: [`TextOut`], the fragment boundary every renderer writes
9//!   to; [`WriteOut`], which coalesces fragments to a byte budget, enforces
10//!   `max_output_bytes` and counts `output_bytes`; [`StringOut`] for tests
11//!   and small results; [`Join`] and [`ReplaceText`], the two text
12//!   combinators whose correctness depends on chunk boundaries, and
13//!   [`Concat`], a `Join` with no separator under the name the language
14//!   gives it.
15//! - [`csv`]: [`CsvRenderer`], the always-quoted profile of `TableRows/1`,
16//!   with [`CsvOptions`] for the dialects.
17//! - [`json`]: [`JsonRenderer`], `JsonEvents/1` as compact or indented
18//!   JSON text.
19//! - [`records`]: [`RecordsToJson`], `TableRows/1` as `JsonEvents/1`, an
20//!   array of objects keyed by label.
21//! - [`number`]: the JSON number grammar both renderers hold lexemes to.
22//! - [`renderers`](mod@renderers): [`RenderRenderers`], this crate's
23//!   implementation of alchemy's `Renderers`, the interface a compiled
24//!   alchemy program makes its rendering stages through.
25//!
26//! The protocols, the text boundary [`TextOut`] and the renderers' options
27//! are tabnas-alchemy's shared types (`tabnas_alchemy::shared`),
28//! re-exported here at the paths they have always had. Every renderer
29//! validates its protocol as it goes and reports the stable codes of
30//! [`tabnas_alchemy::shared::Code`]; the output is flushed once, at the
31//! protocol's end, and a failure found after text was written says so with
32//! `committed_output`.
33
34#![forbid(unsafe_code)]
35
36/// The README's Rust example runs as a doctest, so a stale one fails the
37/// gate rather than misleading the reader.
38#[cfg(doctest)]
39#[doc = include_str!("../../README.md")]
40mod readme_examples {}
41
42pub mod csv;
43pub mod json;
44pub mod number;
45pub mod records;
46pub mod renderers;
47pub mod text;
48
49pub use csv::{CsvOptions, CsvRenderer, MissingText, Newline, Quoting};
50pub use json::{JsonOptions, JsonRenderer};
51pub use number::is_json_number;
52pub use records::{MissingRecord, RecordsToJson};
53pub use renderers::{renderers, RenderRenderers};
54pub use text::{Concat, Join, ReplaceText, StringOut, TextOut, WriteOut, DEFAULT_BUDGET};
55
56/// This crate's version, as `Cargo.toml` declares it.
57pub const VERSION: &str = env!("CARGO_PKG_VERSION");