Skip to main content

kube_seq

Function kube_seq 

Source
pub fn kube_seq<'a, R: KubeReceiver + ?Sized>(
    recv: &'a R,
    field: &str,
) -> Option<&'a Sequence>
Expand description

Read a sub-<field>[] YAML sequence nested one hop under an arbitrary &serde_yaml::Value mapping receiver as Option<&serde_yaml::Sequence> — the value-level two-hop navigation primitive that folds .get(<field>) → as_sequence into a single helper call. Sequence-arity peer of the value-level first-entry accessor kube_seq_first (2d6cb54): the pair closes the (sequence, head-selector) two-arity closure on the value-level axis, mirroring the (kube_spec_seq_field, kube_spec_seq_first) two-arity closure on the spec-anchored axis one altitude above. Where kube_seq_first folds the trailing .first() head-selector onto the two-hop get → as_sequence navigation, this stops at the sequence itself — so a caller enumerating the tail (.iter(), .len(), .filter_map, .expect(...) a full-sequence bind for a downstream length assertion or per-entry walk) reaches for this accessor directly instead of re-inlining the two-line .and_then(|v| v.get(<K>)).and_then(|v| v.as_sequence()) block. Together with kube_seq_first the pair spans the value-level sub-<field>[] axis at both arities: the whole sequence via this accessor, the head entry via the sibling.

Returns None on any of the three short-circuit arms folded through the underlying two-hop composition: the receiver value carries a YAML type without a get(<field>) navigation surface (serde_yaml::Value::get returns None on scalar arms — string, bool, number, null — that expose no per-key lookup), the requested <field> axis-key is absent from the receiver’s mapping (serde_yaml::Value::get trailing miss), or the sub-field value is present but carries a non-sequence YAML type (the trailing .as_sequence() shape-gate short-circuit — a schema-invalid nested- sub-field type per the K8s apiserver’s OpenAPI schema but tolerated here as None so the readback stays a total function). The returned &Sequence borrows into the input Value — the caller decides whether to iterate (.iter()), enumerate for length (.len()), check emptiness (.is_empty()), filter-map by shape (.iter().filter_map(|v| v.as_str())), or commit (.expect(...)).

The canonical shape 11 test-side per-nested-<field>[] sequence readback sites in caixa-mesh and caixa-flux previously carried inline as the two-line composition

<value>
    .and_then(|v| v.get(<FIELD>))
    .and_then(|v| v.as_sequence())
    ...

around a one-token semantic payload (the <FIELD> sub-field axis- key — CILIUM_KEY_TO_PORTS on the per-CNP ingress[0].toPorts[] L4-port bracket, CILIUM_KEY_FROM_ENDPOINTS on the per-CNP ingress[0].fromEndpoints[] source-endpoint bracket, CILIUM_KEY_HTTP on the per-CNP L7 HTTP-rule sequence, GATEWAY_API_KEY_MATCHES on the per-HTTPRoute per-rule matches[] bracket, M2_KEY_UPGRADE_FROM on the caixa-flux per-programs-entry upgradeFrom sequence, FLEET_PROGRAMS_KEY_PROGRAMS on the fleet-programs values.programs[] readback). After this lift every routed consumer folds the two-line navigation onto kube_seq(<value>, <FIELD>) — the two-hop get → as_sequence walk happens once inside the helper, and the caller keeps its downstream idiom (.iter(), .len(), .expect(...), .filter_map(...)) unchanged — the lift closes the navigation surface, not the per-site downstream posture.

Every future nested sub-<field>[] sequence readback (the future per-:politicas CiliumClusterwideEnvoyConfig per-policy nested rule-set walk, the app-operator’s per-Aplicacao mesh.pleme.io/v1alpha1/Aplicacao CR materializer’s nested spec.entrada.paths[] / spec.placement.clusters[] sequences, the future caixa-otel per-Servico OpenTelemetry-Collector CR’s per-receivers.<name>.protocols[] nested sequence, every future test-side nested-sequence probe the M3.x + M4 renderer set adds) reaches this same helper by construction — no per-consumer two-hop chain re-inline, no coordinated rewrite across every nested-sequence bracket on a future serde_yaml surface rebrand or a shift in the shape-gate semantics.