ortho_config 0.9.0

A configuration management library for Rust, inspired by esbuild.
Documentation
//! YAML provider coverage.
//! Ensures `serde-saphyr` integration preserves YAML 1.2 semantics and reports
//! malformed input clearly.

use super::to_anyhow;
use anyhow::{Result, ensure};
use camino::Utf8PathBuf;
use figment::Figment;
use rstest::rstest;
use std::path::PathBuf;

use crate::file::{SaphyrYaml, load_config_file};

#[rstest]
#[case("yes")]
#[case("Yes")]
#[case("YES")]
#[case("no")]
#[case("No")]
#[case("NO")]
#[case("on")]
#[case("On")]
#[case("ON")]
#[case("off")]
#[case("Off")]
#[case("OFF")]
fn yaml_legacy_boolean_literals_remain_strings(#[case] literal: &str) -> Result<()> {
    let path = Utf8PathBuf::from("config.yaml");
    let figment = Figment::from(SaphyrYaml::string(&path, format!("recipient: {literal}")));
    let recipient = figment
        .extract_inner::<String>("recipient")
        .map_err(anyhow::Error::new)?;
    ensure!(recipient == literal, "expected string literal {literal:?}");
    Ok(())
}

#[rstest]
#[case("true", true)]
#[case("false", false)]
fn yaml_respects_boolean_scalars(#[case] literal: &str, #[case] expected: bool) -> Result<()> {
    let path = Utf8PathBuf::from("config.yaml");
    let figment = Figment::from(SaphyrYaml::string(&path, format!("recipient: {literal}")));
    let recipient = figment
        .extract_inner::<bool>("recipient")
        .map_err(anyhow::Error::new)?;
    ensure!(recipient == expected, "expected boolean {expected}");
    Ok(())
}

#[rstest]
fn yaml_loader_reads_files_via_saphyr() -> Result<()> {
    super::with_jail(|jail| {
        jail.create_file("config.yaml", "recipient: friend")?;
        let figment = to_anyhow(load_config_file(PathBuf::from("config.yaml").as_path()))?
            .expect("expected configuration figment");
        let recipient = figment
            .extract_inner::<String>("recipient")
            .map_err(anyhow::Error::new)?;
        ensure!(recipient == "friend", "expected YAML file recipient");
        Ok(())
    })
}

#[rstest]
fn yaml_loader_reports_parse_errors_with_paths() -> Result<()> {
    super::with_jail(|jail| {
        jail.create_file("config.yaml", "recipient: [")?;
        let err = to_anyhow(load_config_file(PathBuf::from("config.yaml").as_path()))
            .expect_err("expected load failure for invalid YAML");
        ensure!(
            err.to_string().contains("config.yaml"),
            "expected error to mention source path, got: {err}"
        );
        Ok(())
    })
}

#[rstest]
#[case("recipient: first\nrecipient: second", "duplicate mapping key")]
#[case("recipient: [", "while parsing")]
fn yaml_provider_surfaces_errors(#[case] contents: &str, #[case] expected: &str) -> Result<()> {
    let path = Utf8PathBuf::from("config.yaml");
    let figment = Figment::from(SaphyrYaml::string(&path, contents));
    let err = figment
        .extract::<crate::serde_json::Value>()
        .expect_err("expected YAML parsing failure");
    ensure!(
        err.to_string().contains(expected),
        "expected error to mention '{expected}', got: {err}"
    );
    Ok(())
}