pub fn string_keyed_entries(
v: &Value,
) -> impl Iterator<Item = (&str, &Value)> + '_Expand description
Iterator over the string-keyed entries of a serde_yaml::Value
that may or may not be a serde_yaml::Mapping — the canonical
shape both per-Servico renderers reach for when splicing the
upstream ComputeUnit YAML’s spec.* fields into their emitted
output map.
Two identical-shape call sites collapse onto this helper — both
per-Servico renderers previously carried a five-line
if let Value::Mapping(_) = spec { for (k, v) in _ { if let Some(s) = k.as_str() { <dst>.insert(s, v.clone()) } } } block:
caixa_flux’sprograms_yaml_entrysplicescomputeunit_yaml.spec.*into the emitted programs.yaml entry (serde_yaml::Mappingdestination, viaMappingExt::insert_str_key);caixa_helm’sbuild_values_yamlsplices the samecomputeunit_yaml.spec.*into the values.yaml wrapped block (std::collections::BTreeMap<String, Value>destination, viaBTreeMap::insert).
Both sites need the same walk (destructure as serde_yaml::Mapping,
iterate its entries, keep only string-keyed pairs, hand the caller
each (&str, &Value) pair) but drop the values into different
destination map types, so the lift is at the iterator layer, not
the insert layer. The caller keeps its own insert idiom (
MappingExt::insert_str_key on a serde_yaml::Mapping,
BTreeMap::insert on the BTreeMap-shaped values block, a
future renderer’s own destination) but reaches through one lifted
walk with one contract on how non-string-keyed entries are handled:
silently dropped, matching the behavior both renderers implemented
inline via the if let Some(s) = k.as_str() filter.
Returns an empty iterator when v is not a
serde_yaml::Value::Mapping — the shape the prior if let Value::Mapping(_) = v arm silently no-ops on (so a Null / String
/ Sequence / Number / Bool spec field, itself schema-invalid
upstream but tolerated by the renderer, contributes zero entries
to the destination map instead of raising a per-shape error).
Non-string-keyed entries within a valid Mapping are silently
dropped — the same behavior the prior if let Some(s) = k.as_str()
arm carried, since serde_yaml permits arbitrary [Value] keys
(numeric, boolean, sub-mapping) that don’t round-trip through the
downstream K8s YAML-key surface (which requires string keys).
The next per-Servico renderer to land — the future per-Servico
OCI packager whose emitted Dockerfile LABEL block spliced through
the same computeunit_yaml.spec.* string-key set, the M4
per-Servico wasm.pleme.io/v1alpha1/ComputeUnit CR materializer
whose emitted spec.* block splices the same set through onto the
typed [kube::api::CustomResource] view, the future caixa-otel
renderer’s per-Servico OpenTelemetry-Collector resource-attribute
splice — gets the canonical string-key filter for free with one
method call, instead of re-inlining the same five-line
if let Value::Mapping(_) = _ walk.