Skip to main content

cli/lib/utils/
mod.rs

1//! Shared utilities used across the Rust CLI.
2
3pub mod extra_args_warning;
4pub mod formatting;
5pub mod get_default_tsconfig_path;
6pub mod gracefully_exit_on_prompt_error;
7pub mod is_module_available;
8pub mod load_configuration;
9pub mod local_binaries;
10pub mod os_info_utils;
11pub mod project_utils;
12pub mod remaining_flags;
13pub mod tree_kill;
14pub mod type_assertions;
15
16pub use formatting::normalize_to_kebab_or_snake_case;
17pub use get_default_tsconfig_path::get_default_tsconfig_path;
18pub use is_module_available::is_module_available;
19pub use remaining_flags::{
20    CommanderOption, camel_case_flag, get_remaining_flags, get_remaining_flags_simple,
21};
22
23pub fn normalize_to_path_case(value: &str) -> String {
24    let mut output = String::with_capacity(value.len());
25    let mut previous: Option<char> = None;
26
27    for character in value.chars() {
28        if character.is_ascii_uppercase()
29            && previous
30                .is_some_and(|previous| previous.is_ascii_lowercase() || previous.is_ascii_digit())
31        {
32            output.push('-');
33        }
34
35        match character {
36            c if c.is_whitespace() => output.push('-'),
37            c if c.is_ascii_alphanumeric() || c == '_' || c == '-' => {
38                output.push(c.to_ascii_lowercase())
39            }
40            _ if !output.ends_with('-') => output.push('-'),
41            _ => {}
42        }
43
44        previous = Some(character);
45    }
46
47    output.trim_matches('-').to_string()
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn normalizes_camel_case() {
56        assert_eq!(normalize_to_kebab_or_snake_case("dryRun"), "dry-run");
57    }
58
59    #[test]
60    fn filters_consumed_remaining_flags() {
61        let args = vec![
62            "nest".to_string(),
63            "build".to_string(),
64            "--watch".to_string(),
65            "--webpack".to_string(),
66        ];
67
68        assert_eq!(
69            get_remaining_flags_simple(&args, &["--watch"]),
70            vec!["--webpack".to_string()]
71        );
72    }
73}