cue-cli 0.2.0

Installed Cue command aggregator and extension dispatcher
Documentation
use std::ffi::OsString;

use anyhow::{Context, Result, bail};
use tracing_subscriber::EnvFilter;

const RUST_LOG_ENV: &str = "RUST_LOG";

pub(crate) fn init_stderr_tracing(default_directive: &str) -> Result<()> {
    tracing_subscriber::fmt()
        .with_env_filter(env_filter_from_env(
            default_directive,
            std::env::var_os(RUST_LOG_ENV),
        )?)
        .with_writer(std::io::stderr)
        .try_init()
        .map_err(|error| anyhow::anyhow!("initialize tracing subscriber: {error}"))
}

fn env_filter_from_env(default_directive: &str, rust_log: Option<OsString>) -> Result<EnvFilter> {
    let Some(rust_log) = rust_log else {
        return default_env_filter(default_directive);
    };
    if rust_log.is_empty() {
        bail!("{RUST_LOG_ENV} must not be empty");
    }
    let Some(rust_log) = rust_log.to_str() else {
        bail!("{RUST_LOG_ENV} must be valid UTF-8");
    };
    EnvFilter::try_new(rust_log).with_context(|| format!("parse {RUST_LOG_ENV} `{rust_log}`"))
}

fn default_env_filter(default_directive: &str) -> Result<EnvFilter> {
    EnvFilter::try_new(default_directive)
        .with_context(|| format!("parse default tracing directive `{default_directive}`"))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn env_filter_uses_default_when_rust_log_is_absent() {
        env_filter_from_env("warn", None).expect("default tracing directive should parse");
    }

    #[test]
    fn env_filter_rejects_empty_rust_log() {
        let error = env_filter_from_env("warn", Some(OsString::new()))
            .expect_err("explicit empty RUST_LOG should fail");

        assert_eq!(format!("{error:#}"), "RUST_LOG must not be empty");
    }

    #[test]
    fn env_filter_rejects_invalid_rust_log_instead_of_falling_back() {
        let error = env_filter_from_env("warn", Some(OsString::from("cue_cli=debug,[")))
            .expect_err("invalid RUST_LOG should fail");

        assert!(
            format!("{error:#}").contains("parse RUST_LOG `cue_cli=debug,[`"),
            "unexpected error: {error:#}"
        );
    }
}