substrate_manager/util/
mod.rs

1use std::path::{Path, PathBuf};
2
3pub use self::config::Config;
4pub use self::errors::{CliError, CliResult, SubstrateResult};
5
6pub mod command_prelude;
7pub mod config;
8pub mod errors;
9pub mod restricted_names;
10
11pub fn normalize_paths(root_path: &Path, path: &Path) -> color_eyre::eyre::Result<PathBuf> {
12    let canonical_parent = if let Some(parent) = path.parent() {
13        cargo_util::paths::normalize_path(&root_path.join(parent))
14    } else {
15        PathBuf::from("")
16    };
17
18    Ok(canonical_parent.join(path.file_name().unwrap()))
19}
20
21pub fn indented_lines(text: &str) -> String {
22    text.lines()
23        .map(|line| {
24            if line.is_empty() {
25                String::from("\n")
26            } else {
27                format!("  {}\n", line)
28            }
29        })
30        .collect()
31}
32
33/// Transform a string to PascalCase string
34pub fn to_pascal_case(string: &str) -> String {
35    let mut chars: Vec<char> = vec![];
36    let mut uppercase_next = false;
37    for (i, ch) in string.chars().enumerate() {
38        if i == 0 {
39            chars.extend(ch.to_uppercase())
40        } else if ch == '_' || ch == '-' {
41            uppercase_next = true;
42        } else if uppercase_next {
43            chars.extend(ch.to_uppercase());
44            uppercase_next = false;
45        } else {
46            chars.push(ch);
47        }
48    }
49
50    String::from_iter(chars)
51}
52
53/// Transform a string to snake_case string
54pub fn to_snake_case(string: &str) -> String {
55    let mut buffer = String::with_capacity(string.len() + string.len() / 2);
56    let mut prev_was_delimiter = true; // Start with true to handle cases where the input starts with a non-alphanumeric character
57
58    for c in string.chars() {
59        if c.is_ascii_alphanumeric() {
60            if c.is_uppercase() {
61                if !prev_was_delimiter && !buffer.is_empty() {
62                    buffer.push('_');
63                }
64                buffer.push(c.to_ascii_lowercase());
65            } else {
66                buffer.push(c);
67            }
68            prev_was_delimiter = false;
69        } else if c == ' ' || c == '-' {
70            if !prev_was_delimiter && !buffer.is_empty() {
71                buffer.push('_');
72            }
73            prev_was_delimiter = true;
74        }
75    }
76
77    buffer
78}
79
80#[cfg(test)]
81mod test {
82    use super::*;
83
84    #[test]
85    fn test_to_pascal_case() {
86        assert_eq!(to_pascal_case("HelloWorld"), "HelloWorld");
87        assert_eq!(to_pascal_case("Hello_World"), "HelloWorld");
88        assert_eq!(to_pascal_case("Hello-World"), "HelloWorld");
89        assert_eq!(to_pascal_case("helloWorld"), "HelloWorld");
90    }
91
92    #[test]
93    fn test_to_snake_case() {
94        assert_eq!(to_snake_case("HelloWorld"), "hello_world");
95        assert_eq!(to_snake_case("Hello_World"), "hello_world");
96        assert_eq!(to_snake_case("Hello-World"), "hello_world");
97        assert_eq!(to_snake_case("hello-world"), "hello_world");
98        assert_eq!(to_snake_case("helloWorld"), "hello_world");
99        assert_eq!(to_snake_case("ABc   wOW"), "a_bc_w_o_w");
100    }
101}