netsuke-build 0.1.0-beta1

A YAML-powered Ninja/Jinja hybrid build system.
//! Parse and hold options for the `which` filter and function.

use minijinja::value::Kwargs;

use crate::localization::{self, keys};

use super::resolve_error::ResolveError;

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub(crate) enum CwdMode {
    #[default]
    Auto,
    Always,
    Never,
}

impl CwdMode {
    pub(super) fn parse(value: &str) -> Option<Self> {
        parse_cwd_mode(value)
    }
}

fn parse_cwd_mode(value: &str) -> Option<CwdMode> {
    match value {
        "auto" => Some(CwdMode::Auto),
        "always" => Some(CwdMode::Always),
        "never" => Some(CwdMode::Never),
        _ => None,
    }
}

#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub(crate) struct WhichOptions {
    pub(super) all: bool,
    pub(super) canonical: bool,
    pub(super) fresh: bool,
    pub(super) cwd_mode: CwdMode,
}

impl WhichOptions {
    pub(crate) fn from_kwargs(kwargs: &Kwargs) -> Result<Self, ResolveError> {
        let all = kwargs.get::<Option<bool>>("all")?.unwrap_or(false);
        let canonical = kwargs.get::<Option<bool>>("canonical")?.unwrap_or(false);
        let fresh = kwargs.get::<Option<bool>>("fresh")?.unwrap_or(false);
        let cwd_mode = kwargs
            .get::<Option<String>>("cwd_mode")?
            .map(|mode| {
                let lower = mode.to_ascii_lowercase();
                CwdMode::parse(&lower).ok_or_else(|| {
                    ResolveError::args(
                        localization::message(keys::STDLIB_WHICH_CWD_MODE_INVALID)
                            .with_arg("mode", mode),
                    )
                })
            })
            .transpose()?;
        Ok(Self {
            all,
            canonical,
            fresh,
            cwd_mode: cwd_mode.unwrap_or_default(),
        })
    }

    pub(crate) fn cache_key_view(&self) -> Self {
        let mut clone = self.clone();
        clone.fresh = false;
        clone
    }
}

impl From<minijinja::Error> for ResolveError {
    fn from(value: minijinja::Error) -> Self {
        Self::args(value)
    }
}