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
26pub 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
44pub 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}