nestrs-cli-rs 0.1.0

Rust port of the Nest CLI for the nestrs organization.
Documentation
//! Rust toolchain discovery for the nestrs compiler path.

use std::path::PathBuf;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RustToolchain {
    pub cargo_binary: PathBuf,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RustToolchainLoader {
    cwd: PathBuf,
    cached: Option<RustToolchain>,
}

impl Default for RustToolchainLoader {
    fn default() -> Self {
        Self::new(std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
    }
}

impl RustToolchainLoader {
    pub fn new(cwd: impl Into<PathBuf>) -> Self {
        Self {
            cwd: cwd.into(),
            cached: None,
        }
    }

    pub fn with_module_paths(cwd: impl Into<PathBuf>, _module_paths: Vec<PathBuf>) -> Self {
        Self {
            cwd: cwd.into(),
            cached: None,
        }
    }

    pub fn load(&mut self) -> Result<RustToolchain, String> {
        if let Some(toolchain) = &self.cached {
            return Ok(toolchain.clone());
        }
        let toolchain = self.resolve().unwrap_or_else(|| RustToolchain {
            cargo_binary: PathBuf::from("cargo"),
        });
        self.cached = Some(toolchain.clone());
        Ok(toolchain)
    }

    pub fn resolve(&self) -> Option<RustToolchain> {
        let local = self
            .cwd
            .join(".cargo")
            .join("bin")
            .join(cargo_binary_name());
        local.exists().then_some(RustToolchain {
            cargo_binary: local,
        })
    }

    pub fn get_module_paths(&self) -> Vec<PathBuf> {
        vec![self.cwd.join(".cargo").join("bin")]
    }
}

fn cargo_binary_name() -> &'static str {
    if cfg!(windows) { "cargo.exe" } else { "cargo" }
}