pub trait EncapsulatesSpecOptionExt {
// Required methods
fn has_mode(&self, kind: EncapsulationMode) -> bool;
fn has_target(&self, kind: EncapsulationTarget) -> bool;
}Expand description
Extension trait on Option<EncapsulatesSpec> — the ONE substrate
primitive that owns the “collapse the parent encapsulates
Option-carrier before probing the inner spec” shape shared by every
downstream require-tag family whose vocabulary reads through
crate::crd::ProcessSpec::encapsulates.
§Why lift
The point-domain require-tag classifier in
tatara-reconciler::bin::tatara-check composed the SAME two-step
chain (spec.encapsulates.as_ref().is_some_and(|e| e.<probe>(k)))
at TWO consecutive rows in evaluate_point_require_tag’s prefix
table:
encapsulation-mode-<kind>— projects onto theEncapsulatesSpec::has_modescalar-carrier probe.encapsulation-target-<kind>— projects onto thecrate::tagged_union::TaggedUnion::haspresence probe over the nestedEncapsulationKindtagged union.
Two restatements of the ONE Option-carrier collapse past the
★★ PRIME-DIRECTIVE ≥ 2 duplication threshold — post-lift ONE
substrate primitive owns the (Option<EncapsulatesSpec>) → probe
discipline, and every current + future presence probe threaded
through spec.encapsulates plugs into it through the SAME trait
shape without a bespoke Option-arm at the caller.
§Semantics vs. the pre-lift chain
.as_ref().is_some_and(|e| e.has_mode(k)) returns false on the
“no encapsulation” outcome (spec.encapsulates == None, e.g., a
greenfield Process that declined the encapsulation surface entirely)
AND on the “encapsulation set but the probed axis doesn’t match”
outcome. The lifted Self::has_mode projection returns false on
the “no encapsulation” outcome and delegates to the inner
EncapsulatesSpec::has_mode on the “encapsulation set” outcome —
observationally equivalent to the pre-lift chain at every callsite.
Symmetric shape for Self::has_target over the nested
EncapsulationKind tagged-union probe.
§Peer to crate::lifetime::Lifetime::ephemeral_exports
Both lifts collapse an Option-carrier at ONE substrate site so
downstream presence probes on the same nested carrier compose
through a uniform shape. ephemeral_exports returns &[ExportSpec]
(empty slice on the collapsed arm; slice methods return false on
empty via .iter().any(...)); this trait returns bool directly
because the two probes on EncapsulatesSpec are not slice-shaped
(a scalar-carrier equality and a tagged-union .has()). Both bind
their respective require-tag families’ probes to a spec.<field> .<probe>(k) shape without an .as_ref().is_some_and(...) chain at
the callsite.
§Compounding
A future third closed-set-driven presence probe reaching through
spec.encapsulates (a hypothetical SubmodeKind scalar on
EncapsulatesSpec, a HandoffPhase closed-set on a new nested
carrier, a further tagged-union discriminator on
EncapsulationKind) lands as ONE more method on this trait +
ONE more if let Some(res) = strip_and_classify_prefixed_kind::<K, _>(tag, "prefix-", |k| spec.encapsulates.<new-probe>(k)) { return res; } branch in the require-tag classifier’s prefix table — no
per-caller .as_ref().is_some_and(...) restatement, no per-caller
spec.encapsulates.as_ref() walk. A future diagnostic shift on the
Option-carrier collapse (surfacing “encapsulation declined” as a
distinct near-miss from “encapsulation set but axis absent”) lands
at THIS ONE substrate owner and every current + future require-tag
family inherits the shift by construction.
Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves
proofs — the Option-carrier collapse lives at ONE substrate site so
every downstream encapsulation-<axis> require-tag family binds
through the SAME shape). THEORY.md §VI.1 (generation over
composition — a new probe on EncapsulatesSpec reaches this trait
through a peer method without a bespoke Option-arm at the caller).
Pinned by
[tests::encapsulates_option_ext_has_mode_returns_false_on_none_for_every_kind],
[tests::encapsulates_option_ext_has_mode_matches_inner_probe_when_present],
[tests::encapsulates_option_ext_has_target_returns_false_on_none_for_every_target],
and
[tests::encapsulates_option_ext_has_target_matches_inner_kind_probe_when_present].
Required Methods§
Sourcefn has_mode(&self, kind: EncapsulationMode) -> bool
fn has_mode(&self, kind: EncapsulationMode) -> bool
True iff this Option<EncapsulatesSpec> is Some(e) AND
EncapsulatesSpec::has_mode on the inner spec answers true
for the given EncapsulationMode. Returns false on None
(a greenfield Process that declined encapsulation entirely) —
including for the default EncapsulationMode::Manage,
because the operator DECLINED the encapsulation surface rather
than defaulting into it.
Sourcefn has_target(&self, kind: EncapsulationTarget) -> bool
fn has_target(&self, kind: EncapsulationTarget) -> bool
True iff this Option<EncapsulatesSpec> is Some(e) AND the
inner EncapsulatesSpec::kind tagged union carries a
populated slot addressed by the given EncapsulationTarget.
Returns false on None.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".