cargo_smith/
utils.rs

1use std::{fs, path::{Path, PathBuf}};
2
3use anyhow::Result;
4
5use crate::templates::{TemplateType, template_engine::TemplateEngine};
6
7pub fn find_matching_parenthesis(content: &str, start_pos: usize) -> Option<usize> {
8    let mut count = 1;
9    let chars: Vec<char> = content[start_pos..].chars().collect();
10    
11    for (i, c) in chars.iter().enumerate().skip(1) {
12        match c {
13            '(' => count += 1,
14            ')' => {
15                count -= 1;
16                if count == 0 {
17                    return Some(start_pos + i);
18                }
19            }
20            _ => {}
21        }
22    }
23    None
24}
25
26/// Create a project folder structure based on a list of directory paths.
27///
28/// Example:
29/// create_project_structure("myapp", &["src/routes", "src/models"]);
30pub fn create_project_structure(
31    project_name: &str,
32    dirs: &[&str],
33) -> Result<()> {
34    let base = Path::new(project_name);
35
36    for dir in dirs {
37        let full_path: PathBuf = base.join(dir);
38        fs::create_dir_all(&full_path)?;
39    }
40
41    Ok(())
42}
43
44// Create the mod generated files in the
45pub async fn generate_mod_files(
46    project_name: &str,
47    files: &[(&str, &str)],
48    template: &TemplateType
49) -> Result<()> {
50    for (path, content) in files {
51        TemplateEngine::generate_from_template(
52            project_name,
53            path,
54            content,
55            template,
56        ).await?;
57    }
58    Ok(())
59}
60
61pub fn to_pascal_case(s: &str) -> String {
62    s.split_whitespace()
63        .filter(|w| !w.is_empty())
64        .map(|w| {
65            let mut c = w.chars();
66            match c.next() {
67                Some(first) => first.to_uppercase().collect::<String>() + c.as_str(),
68                None => String::new(),
69            }
70        })
71        .collect::<String>()
72}
73
74pub fn to_camel_case(s: &str) -> String {
75    let mut words = s.split_whitespace()
76        .filter(|w| !w.is_empty());
77
78    match words.next() {
79        Some(first) => {
80            let mut result = first.to_lowercase();
81            for w in words {
82                let mut c = w.chars();
83                if let Some(first_char) = c.next() {
84                    result.push_str(
85                        &(first_char.to_uppercase().collect::<String>() + c.as_str())
86                    );
87                }
88            }
89            result
90        }
91        None => String::new(),
92    }
93}