Skip to main content

require_valid_versao_requirement

Function require_valid_versao_requirement 

Source
pub fn require_valid_versao_requirement<E>(
    versao: &str,
    on_empty: impl FnOnce() -> E,
    on_invalid: impl FnOnce(String) -> E,
) -> Result<(), E>
Expand description

Bracket a :versao requirement-string axis with the shared “empty-first, then crate::parse_requirement” gate pair every dep-shaped :versao slot carries. Returns on_empty() when versao.is_empty(), on_invalid(reason) when crate::parse_requirement rejects the non-empty input, Ok(()) otherwise.

The empty-first arm strictly precedes the parse arm so a literal "" value surfaces the self-locating empty diagnostic every per-axis error variant already documents an “omit the axis to express any-version” remediation for, rather than the misleading parse-side no-op — crate::parse_requirement("") hits semver::VersionReq::parse("") which returns Ok(VersionReq { comparators: [] }) (semantically identical to semver::VersionReq::STAR), so without the empty-first arm an authored blank :versao "" would silently round-trip as an implicit "*" — the same “silent widening” footgun the peer require_positive_bounded_u32 closes on its zero-floor arm.

The three existing call sites — crate::dep::Dep::validate on crate::dep::Dep::versao (empty → crate::DepError::VersaoEmpty, invalid → crate::DepError::VersaoInvalid), crate::AplicacaoSpec::validate_membros on crate::aplicacao::Membro::versao (empty → crate::AplicacaoError::MembroVersaoEmpty, invalid → crate::AplicacaoError::MembroVersaoInvalid), and crate::SupervisorSpec::validate on crate::supervisor::ChildSpec::versao (empty → crate::SupervisorError::EmptyChildVersion, invalid → crate::SupervisorError::ChildVersaoInvalid) — each formerly inlined this two-arm cascade verbatim. Lifting to one canonical entry-point closes the drift footgun structurally: a future widening of the accepted requirement-shape (a hypothetical git-tag-prefix leniency, a per-axis strictness override, or the M4 typed-resolver’s constraint: axis on [ABSORPTION-ROADMAP.md]’s per-resolver-step trajectory) reaches every dep-shaped :versao consumer by one edit at this helper, not a coordinated rewrite across three modules.

Peer of require_positive_bounded_u32 / require_positive_bounded_u64 on the same closure-based caller-error-variant discipline — the caller owns the enum variant + its self-locating discriminator fields (nome/caixa, versao), this helper only sequences the two gate arms in canonical order and threads the parser’s semver-shaped reason into the invalid arm’s reason: field.

§Errors

Returns on_empty() for versao.is_empty(); returns on_invalid(reason) when crate::parse_requirement rejects the non-empty input (the parser’s to_string() output threaded through as the invalid arm’s reason:); returns Ok(()) otherwise.