Skip to main content

upsert_named_entry

Function upsert_named_entry 

Source
pub fn upsert_named_entry<E>(
    arr: &mut Vec<Value>,
    new_entry: Value,
    name_key: &'static str,
    on_missing_name: impl FnOnce() -> E,
) -> Result<bool, E>
Expand description

Upsert new_entry into a typed sequence of programs.yaml-shaped entries by matching on new_entry’s <name_key> scalar — the idempotent “replace-in-place if present, else append” contract every writer-side aggregator overlay lands the same 11-line block in front of. Returns Ok(true) when the entry was appended new, Ok(false) when an existing entry with the same <name_key> value was replaced in place (preserving position); returns on_missing_name() when new_entry doesn’t carry <name_key> as a string scalar (the caller’s own typed crate::RenderError-shaped error surface, threaded through the closure so this helper stays crate-agnostic).

Two identical-shape call sites collapse onto this helper — the two [caixa-flux] writer-side upsert paths that both land a programs.yaml entry into a programs: sequence differing only on the outer navigation:

Until this lift landed both call sites re-inlined the same verbatim 11-line block — extract-name-scalar-or-error, iterate the sequence, replace-in-place-on-match else fall through to push — with no compile-time link between the two: a rebrand on either side (a per-entry match key rename beyond the currently- lifted crate::FLEET_PROGRAMS_KEY_NAME, the idempotency contract’s semantic reshaping — e.g. matching on (name, namespace) for the M4 multi-namespace aggregator flow once the lareira-fleet-programs chart admits per-entry namespace: overrides, the return-value’s bool-shape shift once “replace” grows a merge-semantics axis) would silently desynchronize the two writer-side paths — one path idempotently upserts under the new contract while the other silently keeps the old shape, and the failure surfaces at aggregator-apply time as a duplicated / missing / mis-merged entry far from the rebrand commit’s source. Peer of the sibling render-side lifts (single_field_overlay, servico_m2_overlay, insert_first_seen) on the same “the same shape written verbatim ≥ 2 times becomes a typed helper” trajectory THEORY.md §I.3.5 promotes to a build-time concern.

The name_key axis stays parametric (rather than pinned to crate::FLEET_PROGRAMS_KEY_NAME inside the helper) so a future per-entry match on a different discriminator scalar (an M4 id: axis promoted alongside name:, the future mesh.pleme.io/v1alpha1/Aplicacao CR materializer’s per-entry spec.selector upsert path) reaches for the same helper with a different key rather than re-inlining the loop. The closure- shaped error surface (rather than a bare Result<bool, &'static str> or an added typed error variant in this crate) keeps every caller’s own error enum authoritative — the diagnostic remediation for a missing-name-scalar in a programs- yaml entry rightly names the caller’s aggregator schema (spec.values.programs[].name for the HelmRelease shape, programs[].name for the bare values.yaml shape), not this generic helper.

§Errors

Returns on_missing_name() when new_entry.get(name_key) is not a serde_yaml::Value::String — the closure surfaces the caller’s own typed error variant naming the offending schema axis. On success returns Ok(true) for a newly-appended entry, Ok(false) for an in-place replacement.