pub enum NodeKind {
}Expand description
The typed variant discriminator on the caixa-ast surface — every
Node’s carrying-shape (atom family, compound family, quote family)
projects through this closed thirteen-arm partition.
The gen_platform::IsVariant derive emits per-arm arm-discriminator
predicates — Self::is_nil, Self::is_symbol, Self::is_keyword,
Self::is_str, Self::is_int, Self::is_float, Self::is_bool,
Self::is_list, Self::is_map, Self::is_vector, Self::is_quote,
Self::is_quasiquote, Self::is_unquote, Self::is_unquote_splice
— so every downstream consumer that only needs the arm-discriminator
projection (not the borrowed field value) reaches for one typed dispatch
on the substrate primitive rather than a hand-rolled
matches!(x.kind, NodeKind::X(_)) literal. Peer of the caixa-core
[caixa_core::CaixaKind] / [caixa_core::CaixaDialeto] /
[caixa_core::DepList] / [caixa_core::UpgradeInstruction] /
caixa-lint / caixa-arch / caixa-provedor / caixa-theme sibling enums
that already carry the gen_platform::IsVariant discipline — the first
closed-set-typed-enum lift on the caixa-ast surface, extending the
discipline onto the AST-node-family axis every downstream authoring
consumer (caixa-fmt, caixa-lint, caixa-lsp) partitions on.
Variants§
Nil
Symbol(String)
Keyword(String)
Str(String)
Int(i64)
Float(f64)
Bool(bool)
List(Vec<Node>)
Map(Vec<Node>)
{ :k v … } — the brace dialect. REAL SYNTAX per
theory/TATARA-LISP-CONSOLIDATION.md D4; 62 live caixa.lisp
manifests author nested maps and are consumed today.
Vector(Vec<Node>)
[ a b … ] — the vector dialect, D4’s sibling.
Quote(Box<Node>)
Quasiquote(Box<Node>)
Unquote(Box<Node>)
UnquoteSplice(Box<Node>)
Implementations§
Source§impl NodeKind
impl NodeKind
pub const fn is_nil(&self) -> bool
pub const fn is_symbol(&self) -> bool
pub const fn is_keyword(&self) -> bool
pub const fn is_str(&self) -> bool
pub const fn is_int(&self) -> bool
pub const fn is_float(&self) -> bool
pub const fn is_bool(&self) -> bool
pub const fn is_list(&self) -> bool
pub const fn is_map(&self) -> bool
pub const fn is_vector(&self) -> bool
pub const fn is_quote(&self) -> bool
pub const fn is_quasiquote(&self) -> bool
pub const fn is_unquote(&self) -> bool
pub const fn is_unquote_splice(&self) -> bool
Source§impl NodeKind
impl NodeKind
Sourcepub const fn as_keyword(&self) -> Option<&str>
pub const fn as_keyword(&self) -> Option<&str>
Substrate-canonical projection onto the Self::Keyword arm’s
borrowed scalar payload — returns Some(&str) byte-borrowed from
the arm’s own String storage, and None on every other arm
of the closed fourteen-arm NodeKind variant set.
Six production consumers today across two caixa-monorepo crates
— the Node::kwarg pair-loop :key value alternator, and the
caixa-lint rule surface’s [caixa_lint::rules]::check_keyword_kebab
walker, check_enum_pascal kwarg-loop filter, keyword_present
walker, matches_kwarg kwarg-loop filter, and items_has_key
kwarg-loop filter — which previously reached the underlying
keyword-name scalar through six raw if let NodeKind::Keyword(k) = &n.kind (or matches!(&n.kind, NodeKind::Keyword(k) if k == key)) open-coded per-arm pattern-matches that expressed no
compile-time link back to the substrate primitive’s typed
scalar-arm projection. A future NodeKind arm addition (a
TaggedKeyword(String, KeywordTag) shape once the tatara-lisp
reader grows a per-keyword scope tag, a NamespacedKeyword(String, String) shape once the sexp→JSON bridge stabilizes the
::ns/key sugar theory/TATARA-LISP-CONSOLIDATION.md D6 sketches)
reaches every downstream per-Keyword-arm consumer through this
one dispatch by construction — no coordinated six-way rewrite
across every per-rule projection site.
Zero-copy — the returned &str borrows from the arm’s own
String storage (pinned by the
as_keyword_is_by_borrow_pointer_identity test), the same
discipline as the sibling [caixa_teia::TeiaValue::as_str]
(7304ffe) / [caixa_teia::TeiaValue::as_object] (7304ffe)
outer-TeiaValue sum-type per-arm projections and the sibling
[caixa_teia::TeiaRefRepr::tipo] (a856d67) /
[caixa_teia::TeiaRefRepr::nome] (15bcdef) /
[caixa_teia::TeiaRefRepr::atributo] outer-TeiaRefRepr scalar
accessors on the substrate’s IaC-side per-(ref …) reference
carrier — one axis level up on the sibling AST-side per-NodeKind
sum-type projection surface.
First Option<&<payload>> projection accessor on the outer
NodeKind sum-type — opens the as_<variant> typed projection
family the sibling per-arm Self::as_symbol (e96eea1) and
Self::as_str projections fold on the same shape at their
consumer surfaces, extending the discipline onto the caixa-ast
per-AST-node-family arm-set every downstream authoring consumer
(caixa-fmt, caixa-lint, caixa-lsp) partitions on.
pub const fn — the body reads the arm discriminant through a
per-arm pattern-match on &self that binds k: &String on the
Keyword arm and projects onto its byte-borrowed &str view via
String::as_str (pub const fn since Rust 1.87, well before
this workspace’s 1.89 MSRV floor); no arm-storage owning-borrow is
taken, no drop is invoked on any arm’s String / Vec<Node> /
Box<Node> payload. Extends the const-eval discipline the sibling
caixa-ast source-position primitive family (Span::new /
Span::point / Span::contains / Span::union / Span::len /
Span::is_empty, Position::new / Position::origin,
line_column) and the paired Self::seq_delims /
Self::reader_macro_prefix writer-half siblings on the
compound-arm / reader-macro-arm sets already carry onto the
caixa-ast NodeKind outer-sum-type’s per-Keyword-arm
borrowed-scalar-projection axis. Every downstream reader that
wants a compile-time keyword-name-arm identity fixture (a const LOOKUP: Option<&str> = NodeKind::Keyword(…).as_keyword(); future
caixa-lint kwarg-key const-lookup table, a per-arm identity oracle
a future caixa-lsp writer const-registry consults at compile time,
a compile-time keyword-arm-set partition truth table the caixa-fmt
writer keys off) now reads through one substrate-primitive const
dispatch rather than being forced onto the runtime code path.
Sourcepub const fn as_symbol(&self) -> Option<&str>
pub const fn as_symbol(&self) -> Option<&str>
Substrate-canonical projection onto the Self::Symbol arm’s
borrowed scalar payload — returns Some(&str) byte-borrowed from
the arm’s own String storage, and None on every other arm
of the closed fourteen-arm NodeKind variant set.
Eight production consumers today across four caixa-monorepo crates
— the caixa-ast Node::head_symbol list-head projection, the
caixa-fmt printer’s special_head_arity head-lookup and
head_symbol_is_command command-head gate, the caixa-lint rule
surface’s check_paired_kwargs positional-KW-head skip,
check_aplicacao_timeout :kind Aplicacao match,
check_git_pin :tipo git matches_kwarg-predicate closure,
and check_consistent_quote (quote …)-form detector, and the
caixa-teia is_ref_form (ref …)-form detector — which
previously reached the underlying symbol-name scalar through
eight raw if let NodeKind::Symbol(s) = &n.kind /
matches!(&n.kind, NodeKind::Symbol(s) if s == "…") /
matches!(items.first().map(|n| &n.kind), Some(NodeKind::Symbol(s)) if s == "…") open-coded per-arm pattern-matches that expressed
no compile-time link back to the substrate primitive’s typed
scalar-arm projection.
Zero-copy — the returned &str borrows from the arm’s own
String storage (pinned by the
as_symbol_is_by_borrow_pointer_identity test), the same
discipline as the sibling Self::as_keyword (6804427) /
[caixa_teia::TeiaValue::as_str] (7304ffe) /
[caixa_teia::TeiaValue::as_object] (7304ffe) outer-sum-type
per-arm projections. Second Option<&<payload>> projection
accessor on the outer NodeKind sum-type — extends the
as_<variant> typed projection family the sibling
Self::as_keyword opened onto the second load-bearing scalar-
arm axis (symbol names — every head symbol lookup, every enum
variant match, every form-head-tag detector) across the
caixa-ast/caixa-fmt/caixa-lint/caixa-teia consumer surface.
pub const fn — sibling in const-eval posture to the peer
Self::as_keyword promotion on the same substrate-primitive
per-arm scalar-projection family; the body is body-preserving
verbatim (same match &self { Self::Symbol(s) => Some(s.as_str()), _ => None } shape, same String::as_str pub const fn const-
stable since Rust 1.87 the Self::as_keyword promotion routes
through), so the promotion extends the const-eval discipline onto
the second per-arm borrowed-scalar-projection axis of the closed
three-arm Keyword / Symbol / Str per-String-arm family the
sibling Self::as_str promotion closes onto the third arm.
Sourcepub const fn as_str(&self) -> Option<&str>
pub const fn as_str(&self) -> Option<&str>
Substrate-canonical projection onto the Self::Str arm’s
borrowed scalar payload — returns Some(&str) byte-borrowed from
the arm’s own String storage, and None on every other arm
of the closed fourteen-arm NodeKind variant set.
Three production consumers today across two caixa-monorepo crates
— the caixa-lint rule surface’s [caixa_lint::rules]::
check_nome_kebab :nome-value kebab-case gate,
check_no_fixme :descricao-value FIXME-placeholder gate, and
the caixa-fmt printer’s is_flag_token -flag/--flag
string-literal command-argument-group detector — which previously
reached the underlying string-literal scalar through three raw
if let NodeKind::Str(s) = &n.kind / matches!(&n.kind, NodeKind::Str(s) if …) open-coded per-arm pattern-matches that
expressed no compile-time link back to the substrate primitive’s
typed scalar-arm projection.
Zero-copy — the returned &str borrows from the arm’s own
String storage (pinned by the
as_str_is_by_borrow_pointer_identity test), the same discipline
as the sibling Self::as_keyword (6804427) / Self::as_symbol
(e96eea1) outer-NodeKind sum-type per-arm projections and the
peer [caixa_teia::TeiaValue::as_str] (7304ffe) outer-TeiaValue
sum-type per-arm projection. Third Option<&<payload>> projection
accessor on the outer NodeKind sum-type — closes the
as_<variant> typed projection family the sibling Self::as_keyword
and Self::as_symbol opened onto the third and final load-
bearing scalar-arm axis (string-literal payloads — every
:nome / :descricao value gate, every -flag token detector,
every quoted-string :kind mis-authoring diagnostic) across the
caixa-lint/caixa-fmt consumer surface.
pub const fn — closes the const-eval-surface promotion the
paired Self::as_keyword / Self::as_symbol siblings opened
onto the third and last per-String-arm axis of the closed
three-arm Keyword / Symbol / Str per-arm scalar-projection
family. Body-preserving verbatim (same match &self { Self::Str(s) => Some(s.as_str()), _ => None } shape, same String::as_str
pub const fn const-stable since Rust 1.87 the two sibling
promotions route through), so every downstream consumer that
wants a compile-time string-literal-arm identity fixture (a
const IS_FLAG: Option<&str> = NodeKind::Str("--flag".into()) .as_str();-shaped future caixa-fmt writer const-lookup table over
a const fixture that widens String::from to const once that
lands upstream, a per-arm identity oracle a future caixa-lint
no-string-literal-in-numeric-position rule consults at compile
time, a compile-time Str-arm-set partition truth table the
caixa-lsp writer keys off) now reads through one substrate-
primitive const dispatch rather than being forced onto the runtime
code path.
Sourcepub const fn as_atom_string(&self) -> Option<&str>
pub const fn as_atom_string(&self) -> Option<&str>
Substrate-canonical projection onto the disjunctive
Self::Symbol | Self::Str | Self::Keyword atom-string-
carrying arm-set — returns Some(&str) byte-borrowed from the
matched arm’s own String storage, and None on every other
arm of the closed fourteen-arm NodeKind variant set.
Two production consumers today across the caixa-teia manifest
parser — the kwarg_symbol :tipo / :nome value-shape gate
((defteia :tipo aws/vpc :nome main …) — accepts a bare symbol,
a quoted "aws/vpc" string, or a :aws/vpc keyword form
depending on author preference) and the build_ref :atributo
slot ((ref aws/vpc main id) / (ref aws/vpc main :id) — the
third position accepts any of the three atom-string-carrying arm
shapes, error-messaged as “must be a symbol/keyword/string”).
Both previously reached the underlying scalar through a raw
three-arm NodeKind::Symbol(s) | NodeKind::Str(s) | NodeKind::Keyword(s) => s.clone() open-coded per-arm disjunctive
pattern-match that expressed no compile-time link back to the
substrate primitive’s typed atom-string-carrying arm-set.
Semantically distinct from the sibling per-arm Self::as_symbol
/ Self::as_str / Self::as_keyword projections — each of
those returns Some(&str) on exactly one arm; this one returns
Some(&str) on the three-arm disjunction of atom-string-carrying
arms. A future NodeKind arm addition that carries a String
payload usable as a name-slot value (a hypothetical
NodeKind::TaggedSymbol(String, SymbolTag) once the tatara-lisp
reader grows a per-symbol scope tag, a NodeKind::NamespacedSymbol (String, String) shape once the sexp→JSON bridge stabilizes the
ns/sym sugar) folds into this projection by extending the
accessor’s arm-set once at the substrate primitive, rather than a
two-way rewrite across every caixa-teia manifest-parser call site.
Zero-copy — the returned &str borrows from the matched arm’s
own String storage (pinned by the
as_atom_string_is_by_borrow_pointer_identity test), the same
discipline as the sibling per-arm Self::as_keyword (6804427)
/ Self::as_symbol (e96eea1) / Self::as_str (55b2909)
scalar-arm projections and the peer [caixa_teia::TeiaValue::as_str]
(7304ffe) outer-sum-type projection. Fourth Option<&<payload>>
projection accessor on the outer NodeKind sum-type — the
first disjunctive accessor on the projection family the three
sibling per-arm accessors already opened, extending the discipline
onto the atom-string-carrying arm-set every caixa-teia name-slot
gate partitions on.
pub const fn — extends the caixa-ast const-eval-surface family
(Span::new / Span::point / Span::contains / Span::union /
Span::len / Span::is_empty / Position::new / Position::origin
/ line_column; the writer-half NodeKind::seq_delims /
NodeKind::reader_macro_prefix; the sibling per-arm
Self::as_keyword / Self::as_symbol / Self::as_str
scalar-projection triple; the compound-arm Self::as_list) onto
the outer-NodeKind sum-type’s disjunctive atom-string-carrying
three-arm projection axis. Body reads the arm discriminant through a
const-friendly match and returns Some(&str) through
String::as_str (pub const fn since Rust 1.87, well before this
promotion) — no interior heap traffic, no trait dispatch, no runtime
operation on the accessor path. A future compile-time caixa-fmt
writer-side per-arm-identity truth-table / caixa-lint keyword-key
const-lookup / caixa-lsp writer const-registry that keys off the
atom-string-carrying three-arm disjunction lands directly on this
accessor without a runtime-context escape hatch.
Sourcepub const fn as_symbol_or_str(&self) -> Option<&str>
pub const fn as_symbol_or_str(&self) -> Option<&str>
Substrate-canonical projection onto the disjunctive
Self::Symbol | Self::Str atom-name-carrying arm-set —
returns Some(&str) byte-borrowed from the matched arm’s own
String storage, and None on every other arm of the closed
fourteen-arm NodeKind variant set.
Two production consumers today across two caixa-monorepo crates
— the caixa-teia build_ref :nome slot ((ref aws/vpc main id)
— the second position accepts either a bare symbol main or a
quoted "main" string, error-messaged as “must be a symbol or
string”) and the caixa-lsp document_symbol :nome-detail
projection (the DocumentSymbol.detail field takes the
:nome value from every top-level (defX …) form, where authors
spell the name as either a bare nome-slug symbol or a quoted
"nome-slug" string). Both previously reached the underlying
scalar through a raw two-arm NodeKind::Symbol(s) | NodeKind::Str(s) => s.clone() open-coded per-arm disjunctive
pattern-match that expressed no compile-time link back to the
substrate primitive’s typed atom-name-carrying arm-set.
Semantically distinct from the sibling three-arm
Self::as_atom_string (3c3ca48) projection — that one accepts
the full atom-string-carrying arm-set including Keyword (a :foo
keyword literal counts as an atom-string in caixa-teia’s
:tipo/:nome / :atributo slot); this one accepts only the
two-arm subset that excludes Keyword, matching the caixa-teia
build_ref :nome gate’s “must be a symbol or string” contract
and the caixa-lsp document_symbol detail’s “bare-symbol or
quoted-string name” author-facing shape.
Zero-copy — the returned &str borrows from the matched arm’s
own String storage (pinned by the
as_symbol_or_str_is_by_borrow_pointer_identity test), the same
discipline as the sibling per-arm Self::as_keyword (6804427)
/ Self::as_symbol (e96eea1) / Self::as_str (55b2909) /
three-arm Self::as_atom_string (3c3ca48) projections and the
peer [caixa_teia::TeiaValue::as_str] (7304ffe) outer-sum-type
projection. Fifth Option<&<payload>> projection accessor on the
outer NodeKind sum-type — the second disjunctive accessor
on the projection family the three sibling per-arm accessors
opened, extending the discipline onto the two-arm atom-name-
carrying subset every caixa-teia build_ref :nome / caixa-lsp
document_symbol :nome-detail site partitions on.
pub const fn — sibling in const-eval posture to the paired
three-arm Self::as_atom_string disjunctive projection, extending
the caixa-ast const-eval-surface family onto the strict-subset
two-arm atom-name-carrying axis. Same match + String::as_str
(pub const fn since Rust 1.87) shape as every other borrowed-&str
projection on the NodeKind outer sum-type — no interior heap
traffic, no trait dispatch, no runtime operation on the accessor
path. Pairs with Self::as_atom_string’s three-arm promotion so
the two disjunctive-arm-set consumer axes on the substrate primitive
(kwarg_symbol :tipo/:nome; build_ref :nome; document_symbol
:nome-detail) route through one const-dispatch pair.
Sourcepub const fn as_list(&self) -> Option<&[Node]>
pub const fn as_list(&self) -> Option<&[Node]>
Substrate-canonical projection onto the Self::List arm’s
borrowed compound payload — returns Some(&[Node]) byte-borrowed
from the arm’s own Vec<Node> storage, and None on every
other arm of the closed fourteen-arm NodeKind variant set.
Eleven production consumers today across four caixa-monorepo crates
— the caixa-ast Node::head_symbol list-head projection and
Node::kwarg :key value pair-loop; the caixa-lint rule
surface’s check_enum_pascal, check_paired_kwargs, and
check_git_pin per-list walkers; the caixa-teia manifest parser’s
instance_from_node :atributos kwargs-list gate; the caixa-fmt
commented_head_degrades_out_of_the_plist_shape printer test’s
list-shape unwrap; the caixa-fmt float_roundtrip reparse test’s
list-shape unwrap; and the caixa-ast parse_list,
parse_map_and_vector, and parse_reader_macros parser tests’
list-shape unwraps — which previously reached the underlying
Vec<Node> child sequence through eleven raw let NodeKind:: List(items) = &X.kind else { … } open-coded per-arm let-else
pattern-matches that expressed no compile-time link back to the
substrate primitive’s typed compound-arm projection.
Semantically distinct from the sibling Map and Vector
compound-arm carrying shapes — every one of those arms also
carries a Vec<Node> payload (Map(Vec<Node>) is the brace
dialect’s { :k v … }; Vector(Vec<Node>) is the bracket
dialect’s [ a b … ]), so a hand-rolled matches!(&_.kind, NodeKind::List(_)) gate has to keep the strict-List-only
boundary in view at every site. This projection pins the boundary
on the substrate primitive — the sibling Map / Vector arms
return None even though they carry the same shape payload —
which is why the seven caixa-lint / caixa-teia / caixa-fmt /
caixa-ast production consumers all reach for the strict List-arm
gate rather than any compound-arm disjunction (a (defcaixa …)
form is a List, not a Map or Vector; a :atributos kwargs
slot is a List, not a Map; the parser’s positional-run detection
runs on List, not the D4 brace/bracket dialect).
Zero-copy — the returned &[Node] borrows from the arm’s own
Vec<Node> storage (pinned by the
as_list_is_by_borrow_pointer_identity test), the same discipline
as the sibling per-arm Self::as_keyword (6804427) /
Self::as_symbol (e96eea1) / Self::as_str (55b2909) scalar
projections and the sibling disjunctive Self::as_atom_string
(3c3ca48) / Self::as_symbol_or_str (fd39cea) two-/three-arm
atom-name projections. Sixth Option<&<payload>> projection
accessor on the outer NodeKind sum-type — the first accessor
on the compound-arm axis (Map/List/Vector all carry
Vec<Node>), extending the projection family from the three
scalar-arm accessors and two disjunctive-scalar-arm accessors onto
the compound-arm axis every downstream authoring-tool and
manifest-parser walker partitions on.
pub const fn — extends the caixa-ast const-eval-surface family
(Self::as_keyword / Self::as_symbol / Self::as_str on
the per-arm scalar axis, Self::seq_delims /
Self::reader_macro_prefix on the outer-NodeKind writer-half
projection axis, crate::Span::new / crate::Span::point /
crate::Span::len / crate::Span::is_empty /
crate::Span::contains / crate::Span::union on the
byte-offset axis, crate::Position::new /
crate::Position::origin / [crate::Position::line_column] on
the 1-indexed line/column axis, crate::Trivia::comment_text
on the trivia-envelope-scoped projection axis) onto the
compound-arm projection axis. The body reaches for
Vec::as_slice on the Self::List borrowed-Vec<Node> slot
— const-stable since Rust 1.7, well before this workspace’s 1.89
MSRV floor — so the promotion is a body-preserving type-signature
widening. Every downstream authoring consumer that wants a
compile-time list-body fixture (a const HEAD: Option<&[Node]> = KIND.as_list(); compile-time oracle a caixa-lint arity gate keys
off, a per-lint const-context list-shape probe an admission
webhook consults) now reads through one substrate-primitive const
dispatch rather than being forced onto the runtime code path.
Sourcepub const fn as_reader_macro_inner(&self) -> Option<&Node>
pub const fn as_reader_macro_inner(&self) -> Option<&Node>
Substrate-canonical projection onto the disjunctive
Self::Quote | Self::Quasiquote | Self::Unquote |
Self::UnquoteSplice reader-macro arm-set — returns
Some(&Node) byte-borrowed from the matched arm’s own
Box<Node> storage, and None on every other arm of the
closed fourteen-arm NodeKind variant set.
Four production consumers today across four caixa-monorepo crates
— the caixa-ast crate::visit::walk visitor recursion, the
caixa-fmt printer’s contains_comment sub-tree comment probe,
the caixa-teia node_to_value manifest lowerer, and the caixa-
lint per-file walk traversal — which previously reached the
underlying inner-node payload through four raw NodeKind::Quote (inner) | NodeKind::Quasiquote(inner) | NodeKind::Unquote(inner) | NodeKind::UnquoteSplice(inner) => recurse(inner) open-coded
four-arm disjunctive pattern-matches that expressed no compile-
time link back to the substrate primitive’s typed reader-macro-
carrying arm-set. Each is a transparent-wrapper unwrap: the
consumer does not care WHICH reader macro variant it is, only
that the wrapper hides an inner Node whose recursion is the
whole traversal.
Semantically distinct from the peer per-arm compound projections
Self::as_list (48efa3b) and from the sibling per-arm scalar
projections Self::as_keyword (6804427) / Self::as_symbol
(e96eea1) / Self::as_str (55b2909) / disjunctive scalar
Self::as_atom_string (3c3ca48) / Self::as_symbol_or_str
(fd39cea) — those project onto borrowed scalars or borrowed
Vec<Node> slices; this one projects onto a borrowed inner
Node, the first projection accessor on the outer-NodeKind
sum-type to reach across the Box<Node> indirection every
reader-macro arm carries. A future reader-macro arm addition (a
hypothetical NodeKind::Splice(Box<Node>) shape once the
tatara-lisp reader grows a splicing-quote variant, a
NodeKind::TaggedQuote(Box<Node>, QuoteTag) shape once the
sexp→JSON bridge stabilizes tagged-quote sugar) folds into this
projection by extending the accessor’s arm-set once at the
substrate primitive, rather than a four-way coordinated rewrite
across every downstream walker.
Zero-copy — the returned &Node borrows from the matched arm’s
own Box<Node> storage (pinned by the
as_reader_macro_inner_is_by_borrow_pointer_identity test), the
same discipline as the sibling per-arm scalar and compound
projections. Seventh Option<&<payload>> projection accessor on
the outer NodeKind sum-type — the first accessor on the
reader-macro arm-family (Quote/Quasiquote/Unquote/UnquoteSplice
all carry Box<Node>), extending the projection family from the
three scalar-arm, two disjunctive-scalar-arm, and one compound-
arm accessors onto the fourth arm-family every downstream
authoring-tool walker and manifest-lowerer partitions on.
pub const fn — closes the const-eval discipline the sibling
caixa-ast source-position primitive family (Span::new /
Span::point / Span::contains / Span::union / Span::len /
Span::is_empty, Position::new / Position::origin,
line_column), the outer-NodeKind per-arm scalar-projection
family (as_keyword / as_symbol / as_str), the two
disjunctive-scalar accessors (as_atom_string /
as_symbol_or_str), the single-arm compound projection
(as_list), and the paired writer-half projections (seq_delims
/ reader_macro_prefix) already carry onto the caixa-ast
NodeKind outer-sum-type’s per-Box<Node>-arm reader-half
projection axis. Body is preserved verbatim: the four-arm
disjunctive match &self binds inner: &Box<Node> and returns
Some(inner), where the compiler’s built-in &Box<T> → &T
return-position coercion sidesteps the Deref trait-dispatch
path (const-stable in Rust since long before this workspace’s 1.89
MSRV floor), so no arm-storage owning-borrow is taken and no drop
is invoked on any arm’s Box<Node> payload. Every downstream
walker that wants a compile-time reader-macro-inner fixture (a
const INNER: Option<&Node> = KIND.as_reader_macro_inner();
compile-time oracle a caixa-lint reader-macro-arity gate keys off,
a per-arm identity oracle a future caixa-lsp writer const-
registry consults at compile time) now reads through one substrate-
primitive const dispatch rather than being forced onto the runtime
code path.
Sourcepub const fn as_seq_body(&self) -> Option<&[Node]>
pub const fn as_seq_body(&self) -> Option<&[Node]>
Substrate-canonical projection onto the disjunctive
Self::List | Self::Map | Self::Vector compound-body
arm-set — returns Some(&[Node]) byte-borrowed from the matched
arm’s own Vec<Node> storage on any of the three D4-dialect
compound-carrying arms (parenthesized list, brace map, bracket
vector), and None on every other arm of the closed
fourteen-arm NodeKind variant set.
Three production consumers today across two caixa-monorepo crates
— the caixa-ast crate::visit::walk visitor recursion (which
treats every compound as a child-bearing container to descend
into), the caixa-fmt printer’s emit_header_operand inlineable
gate (which flattens any D4-dialect compound header operand that
fits the width budget), and the caixa-fmt printer’s is_atom
grid-cell classifier (which refuses any D4-dialect compound as a
grid cell because it carries its own layout) — which previously
reached the underlying Vec<Node> child sequence through three
raw NodeKind::List(items) | NodeKind::Map(items) | NodeKind::Vector(items) => … open-coded three-arm disjunctive
pattern-matches that expressed no compile-time link back to the
substrate primitive’s typed compound-body arm-set. Each site is a
compound-shape-agnostic projection: the consumer does not care
WHICH D4-dialect compound arm it is (the delimiter distinction
matters to per-arm emit sites, not to walkers), only that the
arm hides a Vec<Node> child sequence whose iteration is the
whole traversal.
Semantically distinct from the sibling Self::as_list (48efa3b)
single-arm compound projection — that one pins the strict-List-
only boundary the manifest-parser and positional-classifier sites
gate on (a (defcaixa …) form is a List, not a Map or
Vector); this one lifts the disjunctive three-arm compound-body
arm-set every compound-shape-agnostic walker / header-inliner /
grid-cell classifier reaches for. A future D4-adjacent compound
arm addition (a hypothetical NodeKind::Set(Vec<Node>) shape
once the tatara-lisp reader grows a #{…} set literal, a
NodeKind::Tuple(Vec<Node>) shape once the sexp→JSON bridge
stabilizes fixed-arity tuple sugar) folds into this projection
by extending the accessor’s arm-set once at the substrate
primitive, rather than a three-way coordinated rewrite across
every downstream walker.
Zero-copy — the returned &[Node] borrows from the matched arm’s
own Vec<Node> storage (pinned by the
as_seq_body_is_by_borrow_pointer_identity test), the same
discipline as the sibling per-arm Self::as_list (48efa3b)
compound and Self::as_reader_macro_inner (20be266) reader-
macro projections. Eighth Option<&<payload>> projection
accessor on the outer NodeKind sum-type — extends the
projection family from the two disjunctive-scalar and one
reader-macro-arm-set accessors onto the disjunctive-compound-arm
axis every downstream compound-shape-agnostic walker partitions
on.
pub const fn — sibling in const-eval posture to the paired
single-arm Self::as_list compound projection, extending the
caixa-ast const-eval-surface family onto the disjunctive three-
arm D4-dialect compound-body axis. Body-preserving verbatim
(same match &self { Self::List(items) | Self::Map(items) | Self::Vector(items) => Some(items.as_slice()), _ => None }
shape, same Vec::as_slice pub const fn const-stable since
Rust 1.7 the Self::as_list promotion routes through), so the
promotion is a type-signature widening — no arm-storage owning-
borrow is taken, no drop is invoked on any arm’s Vec<Node>
payload. Closes the const-eval discipline the sibling caixa-ast
source-position primitive family, the outer-NodeKind per-arm
scalar-projection family (as_keyword / as_symbol / as_str),
the two disjunctive-scalar accessors (as_atom_string /
as_symbol_or_str), the single-arm compound projection
(as_list), the paired writer-half projections (seq_delims /
reader_macro_prefix), and the sibling reader-macro-arm reader-
half projection (Self::as_reader_macro_inner) already carry
onto the last remaining Option<&_> projection axis of the
outer-NodeKind sum-type — the disjunctive three-arm compound-
body axis every compound-shape-agnostic walker / header-inliner /
grid-cell classifier partitions on. Pairs with the sibling
writer-half Self::seq_delims promotion so the reader/writer-
duality’s two halves on the D4-dialect compound-arm-set (the
body slice the arm carries, and the two delimiter bytes the arm
reads back as) now BOTH dispatch through one substrate-primitive
const accessor rather than a runtime-context escape hatch on
either half.
Sourcepub const fn seq_delims(&self) -> Option<(char, char)>
pub const fn seq_delims(&self) -> Option<(char, char)>
Substrate-canonical projection onto the delimiter-pair (open, close)
that the tatara-lisp reader consumes to build the three D4-dialect
compound arms — Self::List reads as ('(', ')'), Self::Map as
('{', '}'), Self::Vector as ('[', ']') — and returns None
on every other arm of the closed fourteen-arm NodeKind variant
set. Companion to the sibling Self::as_seq_body compound-body
projection: the reader/writer duality’s two halves — the body slice
the arm carries, and the two delimiter bytes the arm reads back as
— now each dispatch through one substrate accessor rather than a
three-way per-arm pattern-match repeated at every writer site.
Four production consumer sites today in caixa-fmt/src/printer.rs
— the top-level emit main compound-arm dispatch, the
emit_header_operand inlineable branch (previously guarded by
Self::as_seq_body then re-matched with a _ => unreachable!
trap), the render_node_inline inline-render main compound-arm
dispatch, and the classify_is_total_and_names_the_expected_shape
test helper — which previously reached the delimiter pair through
three raw NodeKind::List(_) => Delims::PAREN | NodeKind::Map(_) => Delims::BRACE | NodeKind::Vector(_) => Delims::BRACKET
open-coded per-arm pattern-matches. The doc-comment on caixa-fmt’s
own Delims type already names the invariant this accessor lifts:
“(…), {…} and […] differ ONLY in these two bytes.”
Contract with Self::as_seq_body: for every variant, either both
return Some (the three D4-dialect compound arms) or both return
None (every other arm) — pinned by
seq_delims_partitions_the_same_arm_set_as_as_seq_body. A future
D4-adjacent compound arm addition (a hypothetical
NodeKind::Set(Vec<Node>) shape once the tatara-lisp reader grows
a #{…} set literal) folds onto both accessors at exactly the
substrate — the writer half by extending this partition once, the
walker half by extending Self::as_seq_body’s — rather than a
coordinated rewrite across every per-consumer writer site.
pub const fn — the body reads the arm discriminant through a
_-binding pattern-match that projects onto a Copy-shaped
Option<(char, char)> return, no arm-storage borrow is taken, and
no drop is invoked on any arm’s Vec<Node> payload (the _
pattern binds nothing). Pattern matching on &Self where the
enum carries drop-typed arms has been const-stable in Rust since
long before this workspace’s 1.89 MSRV floor. Extends the
const-eval discipline the sibling caixa-ast source-position
primitive family (Span::new / Span::point / Span::contains
/ Span::union / Span::len / Span::is_empty, Position::new
/ Position::origin, line_column) and the paired
Self::reader_macro_prefix writer-half sibling on the reader-
macro-arm-set already carry onto the caixa-ast NodeKind outer-
sum-type’s per-arm identity-projection axis. Every downstream
writer that wants a compile-time delimiter-pair fixture (a
const PAREN: Option<(char, char)> = NodeKind::List(…).seq_delims(); future caixa-fmt writer
const-lookup table, a per-arm identity oracle a future caixa-lint
no-delimiter-in-non-compound-context rule consults at compile
time, a compile-time compound-arm-set partition truth table the
caixa-lsp writer keys off) now reads through one substrate-
primitive const dispatch rather than being forced onto the
runtime code path.
Sourcepub const fn reader_macro_prefix(&self) -> Option<&'static str>
pub const fn reader_macro_prefix(&self) -> Option<&'static str>
Substrate-canonical projection onto the writer-side sigil prefix
that the tatara-lisp reader consumes to build the four reader-macro
arms — Self::Quote reads as one apostrophe byte, Self::Quasiquote
as one backtick byte, Self::Unquote as one comma byte,
Self::UnquoteSplice as two bytes (comma then at-sign) — and
returns None on every other arm of the closed fourteen-arm
NodeKind variant set. Companion to the sibling
Self::as_reader_macro_inner reader-macro-inner projection: the
reader/writer duality’s two halves on the reader-macro-arm-set —
the boxed inner node the arm carries, and the sigil bytes the arm
reads back as — now each dispatch through one substrate accessor
rather than a four-arm per-arm pattern-match repeated at every
writer site.
Two production consumer sites today in caixa-fmt/src/printer.rs
— the top-level Printer::emit main reader-macro-arm dispatch, and
the peer render_node_inline inline-render main reader-macro-arm
dispatch — which previously reached the sigil bytes through four
raw per-arm pattern-matches (Quote pushing the apostrophe byte,
Quasiquote pushing the backtick byte, Unquote pushing the
comma byte, UnquoteSplice pushing the two-byte comma-then-at-
sign) restated at each site. The fact that the four reader-macro
arms differ ONLY in these one-or-two sigil bytes had no home in
the type system — it lived as prose in the printer’s own arm
dispatch, and a copy-paste that flipped one arm’s sigil (routed
Quote through the backtick byte and Quasiquote through the
apostrophe byte) would silently rewrite every quote as a
quasiquote and vice versa at every writer site.
Contract with Self::as_reader_macro_inner: for every variant,
either both accessors return Some (the four reader-macro arms)
or both return None (every other arm) — pinned by
reader_macro_prefix_partitions_the_same_arm_set_as_as_reader_macro_inner.
A future reader-macro arm addition (a hypothetical
NodeKind::Splice(Box<Node>) shape once the tatara-lisp reader
grows a splicing-quote variant, a NodeKind::TaggedQuote(Box<Node>, QuoteTag) shape once the sexp→JSON bridge stabilizes tagged-quote
sugar — the same extension axis the sibling
Self::as_reader_macro_inner doc-comment names) folds onto both
accessors at exactly the substrate — the writer half by extending
this partition once, the walker half by extending
Self::as_reader_macro_inner’s — rather than a coordinated
rewrite across every per-consumer writer site.
Tenth Option<&<payload>>-shaped projection accessor on the
outer-NodeKind sum-type — the writer-half sibling to
Self::as_reader_macro_inner on the reader-macro-arm-set,
mirroring the shape of the paired
Self::seq_delims / Self::as_seq_body compound-arm-set
accessors on the sibling D4-dialect compound axis. Returns
&'static str rather than a borrow into arm storage because the
sigil bytes are the arm’s IDENTITY (like seq_delims’s
(char, char) pair) rather than a payload the arm carries.
pub const fn — the body reads the arm discriminant through a
_-binding pattern-match that projects onto a Copy-shaped
Option<&'static str> return, no arm-storage borrow is taken, and
no drop is invoked on any arm’s Box<Node> payload (the _
pattern binds nothing). Pattern matching on &Self where the
enum carries drop-typed arms has been const-stable in Rust since
long before this workspace’s 1.89 MSRV floor. Extends the
const-eval discipline the sibling caixa-ast source-position
primitive family (Span::new / Span::point / Span::contains
/ Span::union / Span::len / Span::is_empty, Position::new
/ Position::origin, line_column) already carries onto the
caixa-ast NodeKind outer-sum-type’s per-arm identity-projection
axis. Every downstream writer that wants a compile-time reader-
macro-sigil fixture (a const QUOTE: Option<&'static str> = NodeKind::Quote(…).reader_macro_prefix(); future caixa-fmt writer
const-lookup table, a per-arm identity oracle a future caixa-lint
no-quote-sigil-in-non-reader-macro-context rule consults at
compile time, a compile-time reader-macro-arm-set partition truth
table the caixa-lsp writer keys off) now reads through one
substrate-primitive const dispatch rather than being forced onto
the runtime code path.