Skip to main content

require_v0_servico_shape

Function require_v0_servico_shape 

Source
pub fn require_v0_servico_shape<E>(caixa: &Caixa) -> Result<(), E>
Expand description

Compound V0-shape entry gate: the canonical two-line require_kind(caixa, Servico)? + require_single_servico(caixa)? prelude every per-Servico caixa-<target> renderer runs at its entry-point, collapsed onto one call the caller reads as intent (“gate the input on the V0 Servico shape”) rather than two hand-spelled predicate calls.

The pair names one contract with two axes: :kind is Servico (this is a per-Servico renderer’s input, not a Biblioteca / Binario / Supervisor / Aplicacao mis-hand-off) and :servicos.len() == 1 (the V0 contract every Servico caixa satisfies — one ComputeUnit YAML pointer, matching the one Helm chart / programs.yaml entry / cluster bundle each per-Servico renderer emits). Both axes must hold together — a :kind Servico caixa with two :servicos entries and a :kind Aplicacao caixa with one :servicos entry are equally invalid at every per-Servico renderer’s entry-point — so lifting the pair onto one helper names the compound contract at each call site the way the M2 typed slots’ servico_m2_overlay names the compound :limits+:behavior+ :upgrade-from overlay contract at each call site.

Three production call sites previously carried the two-line pair inline:

Each site now reads caixa_core::require_v0_servico_shape(caixa)? instead of the two-line pair. A future per-Servico renderer (caixa-otel, the future per-Servico OCI packager, the future M4 wasm.pleme.io/v1alpha1/ComputeUnit CR materializer, MESH-COMPOSITION §III.2 #5) gets the compound V0-shape gate for free with one call, instead of re-inlining the two-line pair — and a future change to the V0 contract (e.g. adding a :kind Servico-only :computeunits-slot-shape gate when the component-model multi-world boundary lands in M5) is one edit here, not a coordinated rewrite of every renderer’s inline pair.

The generic error type E accepts every renderer’s local thiserror Error enum that carries both KindMismatch and ServicoCountMismatch via #[from] (caixa_flux::Error, caixa_helm::Error, and every future per-Servico renderer that wires both #[from] arms as the diagnostic-naming-the-offending- caixa contract already requires). Type inference at the call site resolves E from the caller’s ? return type, so the call reads as caixa_core::require_v0_servico_shape(caixa)? with no explicit turbofish — the same one-liner shape every peer require_kind / require_single_servico call site already reads as.

Peer to require_kind on the single-axis kind gate and require_single_servico on the single-axis count gate — both primitives stay public because per-non-Servico renderers (caixa-mesh’s per-Aplicacao gate, caixa-feira’s first_servico_path per-verb gate that composes both predicates with anyhow::Context) reach for the individual predicates rather than the compound one. Peer to servico_m2_overlay on the sibling per-Servico compound-contract surface: servico_m2_overlay names the compound M2 emit-side contract, require_v0_servico_shape names the compound V0 gate-side contract, both per-Servico shape.

§Errors

Returns the caller’s E wrapping a KindMismatch when caixa.kind != CaixaKind::Servico, or a ServicoCountMismatch when caixa.servicos.len() != 1. Order matches the two-line pair this replaces: the kind gate fires first, so a :kind Aplicacao caixa with zero :servicos entries surfaces the kind mismatch (the more actionable diagnostic — the author has the wrong :kind) rather than the count mismatch (a downstream consequence of the mis-kinded input).