pub enum UpgradeInstruction {
LoadModule {
module: String,
},
StateChange {
script: PathBuf,
},
SoftPurge {
module: String,
},
Purge {
module: String,
},
Restart,
}Expand description
One upgrade instruction. The set mirrors OTP’s appup low-level instructions: enough to express every common upgrade pattern, few enough that the wasm-operator can implement each deterministically.
Variants§
LoadModule
Load a new wasm module alongside the current one — the analog
of OTP’s code:load_module/1. Both versions remain in memory
after this instruction; in-flight requests stay on the old
version, new requests route to the new version.
StateChange
Run a state-migration tatara-lisp file. Receives the old state
- the prior version string; returns the new state. Analog of
gen_server:code_change/3.
SoftPurge
Wait for in-flight requests on a named module to drain, then
GC it — the analog of code:soft_purge/1. Default cooldown is
60s; longer-running requests block the upgrade.
Purge
Discard a named module immediately, without waiting for
drain — the analog of code:purge/1. Used when we don’t
care about in-flight callers (cron, oneShot).
Restart
Fall back to a full restart for this entry. Used when a typed upgrade is impossible (e.g. wasm component world incompatible).
Implementations§
Source§impl UpgradeInstruction
impl UpgradeInstruction
Sourcepub const fn discriminant(&self) -> &'static str
pub const fn discriminant(&self) -> &'static str
Stable variant discriminant — auto-generated by
#[derive(Discriminant)]. The string IS the wire
identifier for metrics labels / audit-log tags /
rate-limit keys; renaming an existing variant is a
breaking change.
Source§impl UpgradeInstruction
impl UpgradeInstruction
pub const fn is_load_module(&self) -> bool
pub const fn is_state_change(&self) -> bool
pub const fn is_soft_purge(&self) -> bool
pub const fn is_purge(&self) -> bool
pub const fn is_restart(&self) -> bool
Source§impl UpgradeInstruction
impl UpgradeInstruction
Sourcepub const fn lisp_form(&self) -> &'static str
pub const fn lisp_form(&self) -> &'static str
Substrate-canonical per-UpgradeInstruction OTP-appup kind-tag
projection every consumer that renders / classifies / grepping-
projects an instruction’s lisp form keys off — returns the
kebab-case :kind tag verbatim as a &'static str, threaded
straight through the paired
crate::render::M2_UPGRADE_INSTRUCTION_KIND_LOAD_MODULE /
crate::render::M2_UPGRADE_INSTRUCTION_KIND_STATE_CHANGE /
crate::render::M2_UPGRADE_INSTRUCTION_KIND_SOFT_PURGE /
crate::render::M2_UPGRADE_INSTRUCTION_KIND_PURGE /
crate::render::M2_UPGRADE_INSTRUCTION_KIND_RESTART pub const
roster the substrate already carries at the wire-form axis.
Consumers today: Self::validate threads the label through the
per-variant UpgradeError::ModuleEmpty /
UpgradeError::ModuleInvalid / UpgradeError::PurgeWithoutPriorLoad
/ UpgradeError::DuplicateCleanup diagnostics so the author can
grep their caixa.lisp for (:load-module …) / (:soft-purge …) /
(:purge …) and fix it in one edit; every within-entry cross-
instruction gate on caixa-core/src/upgrade.rs reaches for the
same accessor’s &'static str return in place of hand-rolling
the per-arm match.
Promoted from pub(self) to pub: every future consumer that
wants to render / classify / diagnose an UpgradeInstruction
by its OTP-appup lisp form outside caixa-core — a deferred
wasm-operator install_release/1 per-instruction dispatch
logger tagging each executed instruction under its kebab-case
kind, a feira lint --upgrade-from per-instruction author-time
audit surface, an M4 mesh.pleme.io/v1alpha1/Caixa CR admission
webhook naming the offending instruction’s kind in its rejection
body, a future caixa-actions renderer that surfaces the
declared appup instruction list in a workflow annotation, an
LSP hover projecting the per-instruction kind onto a text-
document diagnostic — reaches this projection through one call
on the substrate primitive rather than open-coding the same
five-arm match plus per-arm const imports at every consumer.
A future variant addition (a Discard peer the code:delete/1
analog inspires, an M4 SoftPurge split into
SoftPurgeCoop / SoftPurgeForce peers as the drain-cool-down
policy grows a two-arm shape) reaches every consumer at one edit
— this method’s match — rather than fanning out through hand-
rolled per-arm dispatch across every downstream site.
Peer of the sibling substrate-canonical arm-family accessors on
the same closed-set enum: Self::declared_module on the
String-carrying axis (Some(_) for Self::LoadModule /
Self::SoftPurge / Self::Purge; None for
Self::StateChange / Self::Restart),
Self::declared_path on the PathBuf-carrying axis
(Some(_) for Self::StateChange), and
the arm-discriminator predicates Self::is_cleanup on the
two-arm cleanup family and the gen_platform::IsVariant-derive-
generated per-variant is_* predicate family — every downstream
consumer that fans on an UpgradeInstruction axis now reaches
one typed dispatch on the substrate primitive rather than open-
coding a per-arm match.
const fn preserves the zero-runtime-work property of the pre-
promotion body verbatim, and the &'static str return (not
&str tied to &self’s lifetime) matches the paired
[crate::render::M2_UPGRADE_INSTRUCTION_KIND_*] const roster’s
program-lifetime discipline so callers can stash the returned
label in &'static-bounded positions (a static logger’s format
argument, a HashMap<&'static str, _> key, a matches!-style
slice-of-&'static str accept-set) without re-borrowing through
the instruction reference. Named lisp_form (not kind_label /
discriminant_label) to name the axis the substrate already
reaches for in the paired
[crate::render::M2_UPGRADE_INSTRUCTION_KIND_*] const roster and
in every per-arm UpgradeError diagnostic that carries the
kebab-case tag verbatim — the lisp author-surface term, not the
Rust discriminant name.
Sourcepub const fn as_str(&self) -> &'static str
pub const fn as_str(&self) -> &'static str
Substrate-canonical per-UpgradeInstruction kebab-case wire-form
discriminator every consumer that lands on the un-prefixed
kebab byte-string (matching serde’s
#[serde(tag = "kind", rename_all = "kebab-case")] derive’s
per-variant tag output and the
gen_platform::Discriminant-derived Self::discriminant
fleet-catalog identity) reaches through — returns "load-module"
/ "state-change" / "soft-purge" / "purge" / "restart",
byte-for-byte the same five strings the JSON "kind" tag carries
(per the sibling
[crate::tests::dispatcher_registration::reflection_round_trips_through_serde_tags]
pin) and the fleet-wide dispatcher-catalog registers under
"caixa.upgrade-instruction" (per
[crate::tests::dispatcher_registration::variant_kinds_match_otp_appup_kebab]).
Distinct axis from the peer Self::lisp_form accessor, which
returns the tatara-lisp author-surface form with the leading :
prefix (":load-module" / ":state-change" / ":soft-purge" /
":purge" / ":restart") that lands in feira lint per-
instruction diagnostics and every
[crate::render::M2_UPGRADE_INSTRUCTION_KIND_*] const’s docstring.
The two axes carry different bytes by design, not drift: the lisp
form is the author-facing tag the caixa.lisp grep-and-fix
workflow reaches for (grep '(:load-module ' finds the offending
entry verbatim), while Self::as_str is the wire-format byte-
string every serde-serialized CR / std::fmt::Display-formatted
diagnostic line / AsRef<str>-bound consumer / fleet-catalog
identity converge onto — the same two-axis discipline the sibling
crate::CaixaKind::as_str / crate::CaixaKind::wire_name
pair (2aa6d23) documents on the top-level :kind closed-set
discriminator, extended here onto the M2 OTP-appup
per-instruction tag axis.
Peer of the sibling closed-set typed enums’ as_str /
as_suffix canonical-projection accessors:
crate::CaixaKind::as_str (6b1f4fb),
crate::supervisor::RestartStrategy::as_str (09ffb2d),
crate::supervisor::RestartPolicy::as_str (ccdf955),
crate::aplicacao::PlacementStrategy::as_str (cc8f749),
crate::aplicacao::RateLimitUnit::as_suffix (6bce03d) — the
last closed-set typed enum on the caixa :upgrade-from surface
to converge onto the substrate-canonical
(as_str, AsRef<str>, Display) triple through one lifted
const fn scalar accessor, so a future author-facing rebrand
(a per-consumer disambiguation of the OTP-appup vocabulary, a
hypothetical :reload collapse of :load-module under an
Elixir/Phoenix hot-reload convergence, an M4-side rename of
:state-change onto Erlang’s own code_change/3 verbatim) lands
at one match arm — the paired std::fmt::Display impl and
AsRef<str> impl route through this accessor by construction,
so every consumer downstream of any of the three reaches the same
per-arm byte-string in lockstep.
pub const fn matches the peer accessors’ const-context posture:
downstream const-context callers (a module-scope
const _:() = assert!(<variant>.as_str().len() > 0) invariant
pin, a const fn per-instruction wire-shape audit table the M4
admission webhook materializes at build time) reach the accessor
through one dispatch on the substrate primitive without an
intermediate non-const step. Returns &'static str (not
&str bound to &self’s lifetime) so callers can stash the
returned label in &'static-bounded positions (a static logger’s
format argument, a HashMap<&'static str, _> key, a matches!-
style slice-of-&'static str accept-set) without re-borrowing
through the instruction reference.
Sourcepub fn validate(&self) -> Result<(), UpgradeError>
pub fn validate(&self) -> Result<(), UpgradeError>
Validate the instruction’s typed shape. Path existence is
checked separately by crate::layout::StandardLayout.
The per-variant scalar the value-shape gates fire against is
read through this method’s two sibling accessors — the
String-carrying axis via Self::declared_module (the
LoadModule / SoftPurge / Purge variants unifying on their
K8s DNS-1123-label :module reference) and the PathBuf-
carrying axis via Self::declared_path (the StateChange
variant’s tatara-lisp :script) — rather than the per-arm
Self::LoadModule { module } | Self::SoftPurge { module } | Self::Purge { module } pattern the module-axis previously
open-coded and the per-arm Self::StateChange { script } the
script-axis previously open-coded. Every scalar this enum
carries now flows through one of the two Option<&…>
accessors, so a future extension of either axis (a fifth
module-bearing variant, an operator-side pre-parsed scalar
cache the accessors materialize behind the same return
contract, an M4 typed sub-slot the accessors could route
alongside the existing scalar) migrates as a single edit on
the accessor rather than a coordinated rewrite of every
downstream value-shape gate. Restart (the only variant that
carries neither scalar) falls through both Option checks and
returns Ok(()) — the terminal-fallback shape the
Self::Restart variant doc pins.
Sourcepub const fn declared_module(&self) -> Option<&str>
pub const fn declared_module(&self) -> Option<&str>
The :module scalar carried by this instruction — the
K8s DNS-1123-label OTP-appup caixa-name reference every
Self::LoadModule / Self::SoftPurge / Self::Purge
variant declares against, and every author expects feira lint
to name verbatim in per-instruction diagnostics. Returns None
on Self::StateChange (which carries a :script — closed by
the sibling Self::declared_path) and on Self::Restart
(which carries no data at all, the OTP terminal-fallback
shape).
Sibling in shape to Self::declared_path on the second and
final scalar-carrying axis of UpgradeInstruction:
declared_path closes the PathBuf-carrying arm
(StateChange); declared_module closes the String-carrying
arms (LoadModule / SoftPurge / Purge). Every scalar the
enum carries now routes through one of the two Option<&…>
accessors — a caller that doesn’t care which variant declared
the scalar reads through one if let Some(…) rather than a
per-variant pattern match. The pair is the enum-variant-
unifying peer of the per-mesh-slot-atom scalar-accessor family
on the M3 side (crate::WitContract::source /
crate::WitContract::destination /
crate::WitContract::world_ref closing :contratos;
crate::Entrada::hostname / crate::Entrada::destination
closing :entrada; crate::Membro::nome /
crate::Membro::versao_requirement closing :membros) and
on the M2 side (crate::UpgradeFromEntry::prior_versao
closing per-entry :from; the crate::LimitsSpec /
crate::BehaviorSpec closed families; the crate::ChildSpec
closed OTP-shape supervisor family) — those peer accessors
return a struct field verbatim; this pair unifies enum-
variant-carried scalars into one accessor per typed axis.
Byte-for-byte from the typed variant’s own String storage;
no cloning, no re-parsing. A future extension of the axis (an
M4 typed sub-slot the module string is derived from, an
operator-side pre-parsed caixa-name cache the accessor could
materialize behind the same &str return contract, a fifth
module-bearing OTP-appup variant the enum grows) migrates as
a single caixa-core edit rather than a coordinated rewrite
of every downstream module-axis consumer (currently
Self::validate’s DNS-1123-label gate through
[validate_module]; extensible to future consumers on the
same axis without further per-variant match sites).
Sourcepub const fn declared_path(&self) -> Option<&PathBuf>
pub const fn declared_path(&self) -> Option<&PathBuf>
If the instruction references an on-disk path, return it — used by the layout checker to verify the path resolves.
Sibling on the PathBuf-carrying axis to Self::declared_module
on the String-carrying axis: declared_path closes the
StateChange arm’s :script; declared_module closes the
LoadModule / SoftPurge / Purge arms’ :module. Together
they route every scalar this enum carries through one of two
Option<&…> accessors, so Self::validate’s value-shape
gates dispatch on the accessor return rather than a per-variant
pattern match on the enum shape itself.
Four per-UpgradeInstruction consumers now key off this
accessor’s PathBuf-carrying axis:
Self::validate’s per-StateChange sandbox-path fan-out,
[crate::layout::StandardLayout::verify]’s per-StateChange
script-existence fan-out at caixa-core/src/layout.rs:1058, the
within-entry
UpgradeFromEntry::validate_state_change_singularity (2bf3ce5)
per-StateChange script-projection fan-out, and the cross-slot
validate_upgrade_from_against_behavior :upgrade-from ↔ :behavior composition gate’s per-StateChange detection loop
— every downstream consumer of the PathBuf-carrying axis
reaches through this one dispatch, so a future accessor
extension (an M4 typed sub-slot the script path is derived from,
an operator-side pre-resolved-path cache the accessor
materializes behind the same Option<&PathBuf> return contract,
a fifth PathBuf-bearing OTP-appup variant the enum grows)
migrates as a single caixa-core edit rather than a coordinated
rewrite of four call sites.
Sourcepub const fn is_cleanup(&self) -> bool
pub const fn is_cleanup(&self) -> bool
Substrate-canonical per-UpgradeInstruction OTP-appup cleanup-
family arm-discriminator predicate every within-entry cross-
instruction cleanup-facing gate keys off — true iff self is
Self::SoftPurge (code:soft_purge/1 analog: drain the
named module until no process is running it, then GC) or
Self::Purge (code:purge/1 analog: discard the named
module immediately, without waiting for drain), the two OTP
two-phase-code-load cleanup arms the closed-set enum’s
non-terminal / non-migration / non-load variants exhaust.
Every non-cleanup arm (Self::LoadModule on the paired
two-phase-load half, Self::StateChange on the
gen_server:code_change/3-analog migration axis,
Self::Restart on the OTP terminal-fallback shape)
returns false.
Prior to this lift the Self::SoftPurge { module } | Self::Purge { module } two-arm cleanup-family pattern-
match sat inline at three within-entry cross-instruction
gate sites, each hand-rolling its own copy of the union
with no compile-time link back to the substrate primitive’s
closed-set arm-family: UpgradeFromEntry::validate_purge_ordering
at caixa-core/src/upgrade.rs:570 (guarded arm firing
UpgradeError::PurgeWithoutPriorLoad on any cleanup
arriving before a preceding Self::LoadModule),
UpgradeFromEntry::validate_state_change_before_cleanup
at caixa-core/src/upgrade.rs:689 (sticky-once latch
recording the first-encountered cleanup so a subsequent
Self::StateChange fires UpgradeError::StateChangeAfterCleanup),
and UpgradeFromEntry::validate_cleanup_singularity at
caixa-core/src/upgrade.rs:800 (per-module cleanup-target
dedup ejecting UpgradeError::DuplicateCleanup on the
second cleanup targeting the same :module). Three open-
coded per-arm-union pattern-matches that expressed no
compile-time link back to the substrate primitive. A future
fifth cleanup-shaped variant (a Discard variant the
code:delete/1 peer inspires that folds under the same
two-phase-load cleanup partition, an M4 SoftPurge split
into SoftPurgeCoop / SoftPurgeForce peers as the drain-
cool-down policy grows a two-arm shape, an operator-side
pre-resolved cleanup-decision cache the predicate could
route through the same bool return contract) would have
had to be threaded through every open-coded per-arm-union
pattern-match in lockstep or one gate would silently
classify the new arm outside the cleanup family while the
peer gates classified it in (or vice versa) — a
classification split across the three within-entry cross-
instruction gates at build time that lands far from the
source UpgradeInstruction declaration with no field
naming which gate carries the drifted arm-set. Lifting the
resolution to a typed predicate on the substrate primitive
means every downstream cleanup-facing consumer of the
UpgradeInstruction closed-set enum reaches for exactly
one typed dispatch — the resolver’s arm-set migrates as a
unit on any future arm addition composing under this
predicate’s || chain.
Sibling in shape to the peer gen_platform::IsVariant-
derive-generated Self::is_restart terminal-fallback
arm-discriminator predicate on the same closed-set
UpgradeInstruction enum (each names an OTP-appup arm-
family partition as one typed dispatch on the substrate
primitive; is_restart on the single-arm terminal-
fallback family, is_cleanup on the two-arm cleanup
family), extended here from the single-arm case onto the
two-arm arm-family union case. Composes through the
gen_platform::IsVariant-derive-generated
Self::is_soft_purge / Self::is_purge per-variant
predicates rather than an open-coded raw matches!
pattern-match, so a future rebrand on either underlying
per-arm classifier flows through this predicate’s one
body without a coordinated per-consumer rewrite across
the three within-entry cross-instruction gates that route
through it. Peer of the sibling per-:contratos
shape-family union predicates crate::WitContract::is_http /
crate::WitContract::is_pubsub / crate::WitContract::is_store
on the M3 mesh-slot per-:wit world-ref axis (each unions a
per-shape WIT-prefix rule the substrate primitive’s arm-
family partition names as one typed dispatch) — the same
“one typed dispatch on the substrate primitive, thin
projections at each consumer” discipline extended onto the
M2 :upgrade-from :instructions per-UpgradeInstruction
cleanup-family axis.
The name is_cleanup maps directly onto the canonical
OTP-appup vocabulary (INSPIRATIONS §II.4 verbatim: “2.
code:soft_purge/1 — wait until no process is running v1,
then discard. (code:purge/1 kills v1 immediately if you
don’t care.)” — the two code:*_purge/1 operations are
the two-phase-load contract’s cleanup half, paired under
one concept), and the peer [Self::validate_cleanup_singularity]
/ UpgradeError::DuplicateCleanup / UpgradeError::PurgeWithoutPriorLoad
/ UpgradeError::StateChangeAfterCleanup surface already
reaches for the same “cleanup” vocabulary in identifier +
diagnostic form.
Trait Implementations§
Source§impl AsRef<str> for UpgradeInstruction
Substrate-canonical AsRef<str> projection on the M2 OTP-appup
per-instruction UpgradeInstruction closed-set typed enum —
routes through the same UpgradeInstruction::as_str
pub const fn scalar accessor the paired std::fmt::Display
impl and the un-renamed serde::Serialize derive already key
off, so any future consumer that binds an UpgradeInstruction
through the standard-library impl AsRef<str> bound (a deferred
wasm-operator per-instruction structured-log recorder that accepts
impl AsRef<str> at the tracing::field::Value Str-arm, a
std::collections::HashMap lookup keyed on the instruction wire
byte through map.get::<str>(instr.as_ref()) on a future
per-instruction dispatch table an M4 admission webhook composes,
a std::process::Command::arg shell-out threading the instruction
tag through a deferred feira upgrade-from --dry-run <kind> verb)
reaches the same kebab-case wire byte-string the
Self::as_str accessor returns through one substrate-primitive
dispatch rather than an open-coded .as_str() projection at
every wire-up.
impl AsRef<str> for UpgradeInstruction
Substrate-canonical AsRef<str> projection on the M2 OTP-appup
per-instruction UpgradeInstruction closed-set typed enum —
routes through the same UpgradeInstruction::as_str
pub const fn scalar accessor the paired std::fmt::Display
impl and the un-renamed serde::Serialize derive already key
off, so any future consumer that binds an UpgradeInstruction
through the standard-library impl AsRef<str> bound (a deferred
wasm-operator per-instruction structured-log recorder that accepts
impl AsRef<str> at the tracing::field::Value Str-arm, a
std::collections::HashMap lookup keyed on the instruction wire
byte through map.get::<str>(instr.as_ref()) on a future
per-instruction dispatch table an M4 admission webhook composes,
a std::process::Command::arg shell-out threading the instruction
tag through a deferred feira upgrade-from --dry-run <kind> verb)
reaches the same kebab-case wire byte-string the
Self::as_str accessor returns through one substrate-primitive
dispatch rather than an open-coded .as_str() projection at
every wire-up.
Peer of the sibling std::fmt::Display impl on the same
primitive — both delegate to the shared
UpgradeInstruction::as_str pub const fn accessor, so
format!("{v}"), v.as_str(), and
<UpgradeInstruction as AsRef<str>>::as_ref(&v) resolve to the
same byte-string per instance by construction. A future variant
rename or #[serde(rename_all = "…")] attribute-drift on the enum
reaches every one of the three paths (plus the wire-format
Serialize derive that already routes through the same kebab
vocabulary and the gen_platform::Discriminant-derived
Self::discriminant catalog identity) through exactly one
caixa-core edit — the Self::as_str match arms.
Same “route the trait impl through the substrate-primitive
accessor” discipline the sibling
crate::supervisor::RestartStrategy AsRef<str> impl
(63eb1a4), crate::supervisor::RestartPolicy AsRef<str>
impl (419ea81), crate::aplicacao::PlacementStrategy
AsRef<str> impl (d86edd2), crate::CaixaKind
AsRef<str> impl (cd2091f), crate::aplicacao::RateLimitUnit
AsRef<str> impl (d8136db), and crate::CaixaVersion
AsRef<str> impl (16d5c7e) carry — closes the substrate
primitive’s AsRef<str> projection axis onto the last M2
OTP-shape closed-set typed enum on the caixa :upgrade-from
surface, so every closed-set typed enum on the caixa typed
surface now carries the paired AsRef<str> +
[fmt::Display] + as_str triple.
Pinned load-bearing by
[tests::upgrade_instruction_as_ref_str_routes_through_as_str_accessor]
— any future silent detour that routes the impl through a
divergent projection (a per-arm inline match self { … }
re-inlining that opens a compile-time link to the un-lifted arm-
literal, a swap onto the Self::lisp_form tatara-lisp axis
that would collide the wire axis with the author-surface axis)
trips at caixa-core test time under assert_eq! rather than at a
downstream impl AsRef<str>-bound consumer’s silent split.
Source§impl Clone for UpgradeInstruction
impl Clone for UpgradeInstruction
Source§fn clone(&self) -> UpgradeInstruction
fn clone(&self) -> UpgradeInstruction
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for UpgradeInstruction
impl Debug for UpgradeInstruction
Source§impl<'de> Deserialize<'de> for UpgradeInstruction
impl<'de> Deserialize<'de> for UpgradeInstruction
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Display for UpgradeInstruction
std::fmt::Display routed through UpgradeInstruction::as_str,
so the pretty-printed byte-string every consumer that formats the
per-:upgrade-from :instructions entry’s OTP-appup tag as user-
facing text lands on (the future wasm-operator’s
install_release/1 per-instruction dispatch log line, the future
feira lint --upgrade-from per-entry annotation, an M4
mesh.pleme.io/v1alpha1/Caixa CR admission-webhook rejection body
naming the offending instruction’s kind, an LSP hover projecting
the instruction kind onto a text-document diagnostic) reaches for
the same wire byte-string the un-renamed
#[serde(tag = "kind", rename_all = "kebab-case")] derive emits
under the paired crate::render::M2_UPGRADE_INSTRUCTION_KEY_KIND
tag key.
impl Display for UpgradeInstruction
std::fmt::Display routed through UpgradeInstruction::as_str,
so the pretty-printed byte-string every consumer that formats the
per-:upgrade-from :instructions entry’s OTP-appup tag as user-
facing text lands on (the future wasm-operator’s
install_release/1 per-instruction dispatch log line, the future
feira lint --upgrade-from per-entry annotation, an M4
mesh.pleme.io/v1alpha1/Caixa CR admission-webhook rejection body
naming the offending instruction’s kind, an LSP hover projecting
the instruction kind onto a text-document diagnostic) reaches for
the same wire byte-string the un-renamed
#[serde(tag = "kind", rename_all = "kebab-case")] derive emits
under the paired crate::render::M2_UPGRADE_INSTRUCTION_KEY_KIND
tag key.
Peer of the sibling closed-set typed enums’ Display route through
their as_str accessor: crate::CaixaKind (2aa6d23),
crate::supervisor::RestartStrategy (supervisor.rs),
crate::supervisor::RestartPolicy (supervisor.rs), and
crate::aplicacao::PlacementStrategy (aplicacao.rs) — the last
M2 OTP-shape closed-set typed enum on the caixa :upgrade-from
surface to converge onto the Display-through-as_str discipline.
Deliberately routes through the wire-aligned
UpgradeInstruction::as_str axis (kebab-case, no : prefix),
not the tatara-lisp author-surface UpgradeInstruction::lisp_form
axis (kebab-case, with : prefix): the two axes carry different
bytes by design, and Rust convention pairs std::fmt::Display
with the wire byte-string every serde-carried CR / structured-log /
catalog identity reaches. The two-axis split is preserved
structurally by the pin
[tests::upgrade_instruction_display_matches_as_str_and_not_lisp_form]
so a future accidental collapse (routing Display through
Self::lisp_form via a mistaken match-arm re-inlining) trips at
caixa-core test time rather than silently merging the two axes at
some future consumer’s per-instruction dispatch step.
Discards the per-variant scalar data (module: String on
LoadModule / SoftPurge / Purge; script: PathBuf on
StateChange) by design — the Display axis is the tag
projection, not a full value dump; consumers wanting the field
scalar reach for Self::declared_module /
Self::declared_path on the sibling scalar-accessor family. The
{:?} std::fmt::Debug derive stays untouched for callers that
want the full variant + field rendering.
impl Eq for UpgradeInstruction
Source§impl PartialEq for UpgradeInstruction
impl PartialEq for UpgradeInstruction
Source§impl Serialize for UpgradeInstruction
impl Serialize for UpgradeInstruction
impl StructuralPartialEq for UpgradeInstruction
Source§impl TypedDispatcher for UpgradeInstruction
impl TypedDispatcher for UpgradeInstruction
Source§fn variant_kinds() -> Vec<&'static str>
fn variant_kinds() -> Vec<&'static str>
Source§fn variant_fields() -> Vec<(&'static str, Vec<&'static str>)>
fn variant_fields() -> Vec<(&'static str, Vec<&'static str>)>
inherit (variant) <fields> Nix patterns.Source§fn variant_count() -> usize
fn variant_count() -> usize
Auto Trait Implementations§
impl Freeze for UpgradeInstruction
impl RefUnwindSafe for UpgradeInstruction
impl Send for UpgradeInstruction
impl Sync for UpgradeInstruction
impl Unpin for UpgradeInstruction
impl UnsafeUnpin for UpgradeInstruction
impl UnwindSafe for UpgradeInstruction
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.