1use clap::Args;
2use std::error::Error;
3use std::path::Path;
4use std::{env, fs, io};
5
6#[derive(Args, Debug)]
8pub struct NewArgs {
9 pub package_name: String,
11}
12
13pub const HTTP_CARGO_TOML: &str = include_str!("../template/notCargo.toml");
14pub const HTTP_LIB_RS: &str = include_str!("../template/lib.rs");
15pub fn handle_new(args: &NewArgs) -> Result<(), Box<dyn Error>> {
16 dbg!(&args);
17 let current_dir = env::current_dir()?;
18 let new_project_dir = current_dir.join(&args.package_name);
19
20 if new_project_dir.exists() && !args.package_name.is_empty() {
21 return Err(format!("Directory '{}' already exists", args.package_name).into());
22 }
23 if new_project_dir.join("Cargo.toml").exists() {
24 return Err(format!(
25 "Cargo.toml already exists in '{}'",
26 new_project_dir.display()
27 )
28 .into());
29 }
30 fs::create_dir_all(new_project_dir.join("src"))?;
31 let pkg_name = if args.package_name.is_empty() {
32 "axum_serverless"
33 } else {
34 &*args.package_name
35 };
36
37 write_files(&new_project_dir, HTTP_CARGO_TOML, HTTP_LIB_RS, pkg_name)?;
38
39 println!(
40 "Successfully created new Axum project '{}' at '{}'",
41 args.package_name,
42 new_project_dir.display()
43 );
44 Ok(())
45}
46
47fn write_files(
50 project_dir: &Path,
51 cargo_toml_str: &str,
52 main_rs_str: &str,
53 package_name: &str,
54) -> io::Result<()> {
55 let cargo_toml_path = project_dir.join("Cargo.toml");
59 let updated_cargo_toml = rewrite_package_name(cargo_toml_str, package_name);
60 fs::write(cargo_toml_path, updated_cargo_toml)?;
61
62 let main_rs_path = project_dir.join("src").join("lib.rs");
64 fs::write(main_rs_path, main_rs_str)?;
65
66 Ok(())
67}
68
69fn rewrite_package_name(toml_input: &str, package_name: &str) -> String {
71 let mut in_package = false;
72 let mut output = String::new();
73
74 for line in toml_input.lines() {
75 let trimmed = line.trim_start();
76 if trimmed.starts_with("[package]") {
77 in_package = true;
78 output.push_str(line);
79 output.push('\n');
80 continue;
81 }
82
83 if in_package && trimmed.starts_with("name =") {
84 output.push_str(&format!("name = \"{package_name}\"\n"));
85 in_package = false; continue;
87 }
88
89 output.push_str(line);
90 output.push('\n');
91 }
92
93 output
94}