nestrs-cli-rs 0.1.0

Rust port of the Nest CLI for the nestrs organization.
Documentation
//! Upstream source: `../nest-cli/lib/utils/project-utils.ts`.

use crate::commands::{Input, InputValue};
use crate::configuration::{Configuration, GenerateSpec, ProjectConfiguration};

pub fn should_ask_for_project(
    schematic: &str,
    configuration_projects: &std::collections::BTreeMap<String, ProjectConfiguration>,
    app_name: &str,
) -> bool {
    !matches!(schematic, "app" | "sub-app" | "library" | "lib")
        && !configuration_projects.is_empty()
        && app_name.is_empty()
}

pub fn should_generate_spec(
    configuration: &Configuration,
    schematic: &str,
    app_name: &str,
    spec_value: bool,
    spec_passed_as_input: Option<bool>,
) -> bool {
    if spec_passed_as_input == Some(true) || spec_passed_as_input.is_none() {
        return spec_value;
    }

    if let Some(value) = spec_value_for(&configuration.generate_options.spec, schematic) {
        return value;
    }

    if !app_name.is_empty() {
        if let Some(value) = spec_value_for(&configuration.generate_options.spec, schematic) {
            return value;
        }
    }

    spec_value
}

pub fn should_generate_flat(
    configuration: &Configuration,
    _app_name: &str,
    flat_value: bool,
) -> bool {
    if flat_value {
        return true;
    }
    configuration.generate_options.flat.unwrap_or(flat_value)
}

pub fn get_spec_file_suffix(
    configuration: &Configuration,
    _app_name: &str,
    spec_file_suffix_value: &str,
) -> String {
    if !spec_file_suffix_value.is_empty() {
        return spec_file_suffix_value.to_string();
    }

    configuration
        .generate_options
        .spec_file_suffix
        .clone()
        .unwrap_or_else(|| "spec".to_string())
}

pub fn move_default_project_to_start(
    configuration: &Configuration,
    default_project_name: &str,
    default_label: &str,
) -> Vec<String> {
    let mut projects = configuration.projects.keys().cloned().collect::<Vec<_>>();
    if configuration.source_root != "src" {
        let default_without_label = default_project_name.replace(default_label, "");
        projects.retain(|project| project != &default_without_label);
    }
    projects.insert(0, default_project_name.to_string());
    projects
}

pub fn has_valid_option_flag(
    queried_option_name: &str,
    options: &[Input],
    queried_value: Option<&InputValue>,
) -> bool {
    options.iter().any(|option| {
        option.name == queried_option_name
            && match (&option.value, queried_value) {
                (Some(value), Some(queried_value)) => value == queried_value,
                (Some(InputValue::Bool(true)), None) => true,
                _ => false,
            }
    })
}

fn spec_value_for(spec: &Option<GenerateSpec>, schematic: &str) -> Option<bool> {
    match spec {
        Some(GenerateSpec::Bool(value)) => Some(*value),
        Some(GenerateSpec::BySchematic(options)) => options.get(schematic).copied(),
        None => None,
    }
}