tatara-closed-set 0.3.4

ClosedSet — the typed witness for the closed-set-enum idiom (ALL + label + parse_label + typed parse-rejection carrier)
Documentation

[ClosedSet] — the typed witness for the closed-set-enum idiom.

The substrate carries 36+ closed-set enums (AtomKind, QuoteForm, SexpShape, MacroDefHead, UnquoteForm, KwargPathKind, ExpectedKwargShape, CompilerSpecIoStage in this crate; ProcessPhase, ConditionKind, IntentKind, LifetimeKind, TeardownPolicy, ProcessSignal, ArtifactKind, ReportFormat, ChannelKind, ExportTrigger, ReceiptKind, RequestorKind, SelectStrategyKind, EncapsulationMode, EncapsulationTarget, DataClassification, AllocationPhase, CalmClassification, OptimizationDirection, HorizonKind, SubstrateType, ConvergencePointType, MemberState, PoolPhase, ReplacementPolicy, ReturnPolicy, AutoTerminateKind, TerminateReasonKind, VerificationPhase, WorkloadKind, MustReachPhase, SighupStrategy, BreatheDimensionKind, MatrixTarget, ReportPayloadShape, … in tatara-process). Each one independently re-derives the same four-piece shape:

  1. pub const ALL: [Self; N] = [...] — the forced-arity array literal that fails compilation if a new variant lands without being added to the set.
  2. fn label(self) -> &'static str (or its domain-canonical sibling — prefix, marker, keyword, as_str) — the typed projection from variant to the canonical &'static str literal the diagnostic / wire format uses.
  3. impl FromStr whose body is a linear sweep over Self::ALL keyed on the projection — exactly the same 6-line for-loop / Err(Unknown<TypeName>(s.to_owned())) shape every implementor re-derives byte-for-byte.
  4. pub struct Unknown<TypeName>(pub String) with #[error("unknown <thing>: {0}")] — the typed parse-rejection carrier that hands the offending input back unchanged.

Pieces 1, 2, 4 carry per-variant content (the variants themselves, their canonical labels, the rejection-class wording) and stay per-implementor. Piece 3 — the for-loop sweep — is mechanically identical across every implementor and is the duplication this trait lifts.

Trait surface

pub trait ClosedSet: Sized + Copy {
    const ALL: &'static [Self];
    type Unknown;
    fn label(self) -> &'static str;
    fn make_unknown(s: &str) -> Self::Unknown;

    // Default — the lifted for-loop body.
    fn parse_label(s: &str) -> Result<Self, Self::Unknown> { ... }
}

A typical implementor wires in three lines beyond its existing inherent surface, and its hand-rolled FromStr body collapses from six lines to one:

impl ClosedSet for AtomKind {
    const ALL: &'static [Self] = &Self::ALL;
    type Unknown = UnknownAtomKind;
    fn label(self) -> &'static str { AtomKind::label(self) }
    fn make_unknown(s: &str) -> Self::Unknown { UnknownAtomKind(s.to_owned()) }
}

impl FromStr for AtomKind {
    type Err = UnknownAtomKind;
    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        <Self as ClosedSet>::parse_label(s)
    }
}

Implementors with a non-label inherent projection name (QuoteForm::prefix, UnquoteForm::marker, MacroDefHead::keyword, tatara_process's *::as_str) delegate ClosedSet::label to their domain-canonical method — the trait method gives every implementor a STABLE name (label), with the inherent name kept as the load-bearing domain-vocabulary projection (prefix for homoiconic reader-form, marker for template-substitution punctuation, keyword for macro-head reserved word, as_str for tatara-process's PascalCase wire format).

Theory grounding

THEORY.md §V.1 — knowable platform; the for-loop / Unknown- emission pattern was a known idiom carried by convention across 36+ implementors. This trait makes the idiom a TYPED WITNESS — any new closed-set enum that implements ClosedSet plugs into the trait's default parse_label and a future generic consumer (a metrics tagger, a Lisp keyword completer, an iac-forge canonical-form renderer over closed-set kinds) can take a T: ClosedSet parameter and walk the set without knowing which crate it lives in.

THEORY.md §VI.1 — generation over composition; the trait IS the generative shape. New closed-set enums add the trait impl + the one-line FromStr delegation instead of re-deriving the for-loop body, and the parse-rejection diagnostic surface narrows from "36+ independent sweeps that must each be kept symmetric" to "one default body, 36+ impls of a four-method contract."

Provenance

This crate is pleme-io/tatara's tatara-lisp/src/closed_set.rs moved verbatim, per theory/TATARA-LISP-CONSOLIDATION.md phase 2 step 1. tatara-lisp neither carries nor re-exports ClosedSet: that is the property that keeps the published tatara-lisp small enough for the phase-3 facade, and it is enforced structurally — this crate depends on tatara-lisp (for the one shared domain::suggest metric), so the reverse edge would be a cargo dependency cycle and cannot be written.

The trait body is byte-identical to its pre-split form apart from crate::domain::suggesttatara_lisp::domain::suggest and the doc-links that pointed at sibling modules which stayed in tatara-lisp. Nothing about the wire surface (label / parse_label / the "unknown {SET_LABEL}: {input}" carrier rendering) was reshaped — the implementors serialize Kubernetes CRD state through it.