pub trait JsonMapStrExt {
// Required method
fn insert_str(
&mut self,
key: impl Into<String>,
value: impl Into<String>,
) -> Option<Value>;
}Expand description
Substrate extension trait over serde_json::Map<String, Value> —
the ONE substrate owner of the map.insert(<key>.into(), Value::String(<val>.into())) string-slot insertion shape every
JSON-mutating helper in the workspace hand-authored at each callsite.
Peer of ValueObjectExt above on the JSON-mutation axis, split
by SHAPE: ValueObjectExt::as_object_mut_or owns the “walk into
this Value’s object-shape interior or fail loud” guard;
JsonMapStrExt::insert_str owns the “stamp a Value::String at
a string-typed key” write shape that every consumer downstream of
the guard uses to populate the returned &mut Map.
Pre-lift the shape was hand-authored at SEVENTEEN production emit
sites across tatara-reconciler past the ★★ PRIME-DIRECTIVE ≥ 2
duplication threshold:
ssapply::inject_annotations× 4 — the SSA-time observed-* annotation stamp family (PID,CONTENT_HASH,GENERATION,ATTESTATION_ROOT) each restated the 2-lineannot.insert( <annotation-const>.to_string(), Value::String(<val>.<coerce>))shape verbatim.render::render_flux× 3 — the FluxKustomization.specseeds (interval,path,targetNamespace), each restating the samespec.insert("<key>".into(), Value::String(<val>))shape.render::render_aplicacao× 3 — the FluxHelmRelease.specseeds (releaseName,targetNamespace) plus the values-overlayprofileslot, each restating the same insert shape.render::render_export_job× 2 — the export-Job outer label map (ROLE,EXPORT_INDEX) each restating the same insert shape.edges::IngressEdge::render× 1 — the cert-managercluster-issuerannotation, restating the same insert shape.edges::routing_edge_labels× 2 — the routing-edgemetadata. labelsmap’s non-ownership slots (APP,ROUTING_FORM), each restating the samelabels.insert(<annotation-const>.to_string(), Value::String(<val>.into()))shape past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold — one of TWO adjacent bypass sites the substrate owner reaches through this lift.render::mark_resources_as_adopting× 2 — theencapsulation- mode+adopted-releaseannotation stamps on adoption-mode render, each restating the sameanns_obj.insert("<key>".into(), Value::String(<val>.into()))shape past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold. The adopted-release value slot also routes its<ns>/<release>join through the siblingcrate::qualified_process_refsubstrate composer, closing a bareformat!("{ns}/{name}")bypass on the<ns>/<name>join axis at this same callsite.
All SEVENTEEN pre-lift sites restated the SAME 2-line shape verbatim,
differing only in the &'static str / String key + the &str /
String value at each callsite. A copy-paste that dropped the
Value::String(...) wrap (a caller who reached for
.insert(k, v) after refactoring from a Value slot to a plain
String value slot) would type-check silently at every callsite —
Map<String, Value>::insert expects a Value, and String: Into<Value> is provided by serde_json via the Value::String
arm’s From impl, so the naive .insert(k, v.to_string()) compiles
AND writes the byte-identical JSON. Post-lift each callsite reads
<map>.insert_str(<key>, <val>) and the string-slot write shape
lives at ONE substrate owner here.
§Composability
- Key slot accepts any
impl Into<String>:&str(viaString::from),String(identity),Cow<'_, str>, so a callsite with a staticannotations::PID(&'static str) readsinsert_str(annotations::PID, …)with no.to_string()per site. - Value slot accepts any
impl Into<String>:&str,String,Cow<'_, str>. Numeric or non-string values still need an explicit.to_string()at the callsite — same as pre-lift, so the wrapping shape stays visible in the caller’s grep footprint. - Returns
Option<Value>matching the inherentMap<String, Value>::insertreturn semantics:Noneon new-key,Some(prev)on overwrite of an existing slot.
§Naming — insert_str, not insert
Same discipline as ValueObjectExt::as_object_mut_or above — the
trait method deliberately does NOT collide with the inherent
Map::insert (which takes (String, Value) positionally). A name
collision would let a caller who has JsonMapStrExt in scope
resolve to the inherent method by accident (inherent methods win
over trait methods in method resolution) and silently drop the
Value::String wrap, stamping the value bytes straight into the
map under a different Value variant. The _str suffix names the
intent: the value slot IS the Value::String arm at this write.
Theory anchor: THEORY.md §VI.1 (generation over composition — the
.insert(<k>.into(), Value::String(<v>.into())) shape recurred at
SEVENTEEN hand-authored sites past the ★★ PRIME-DIRECTIVE ≥ 2
duplication trigger, and is lifted to ONE substrate owner here).
THEORY.md §II.1 invariant 5 (composition preserves proofs — a
regression that drifts the string-slot write shape at ONE consumer
surfaces at the substrate pin rather than as silent per-emit skew
across every ssapply / render / edges JSON emit site).
Required Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".