1use super::{
7 extract_param, generate_file, generator::generate_files,
8 generators::csv::generate_from_csv,
9 generators::ini::generate_from_ini,
10 generators::json::generate_from_json,
11 generators::toml::generate_from_toml,
12 generators::yaml::generate_from_yaml,
13 models::model_params::FileGenerationParams,
14};
15use clap::ArgMatches;
16use regex::Regex;
17use std::error::Error;
18
19pub fn process_arguments(
31 matches: &ArgMatches,
32) -> Result<(), Box<dyn Error>> {
33 match matches.subcommand() {
34 Some(("file", file_matches)) => {
35 if let Some(value) = file_matches.get_one::<String>("csv") {
36 generate_file!("csv", value, generate_from_csv);
37 }
38 if let Some(value) = file_matches.get_one::<String>("ini") {
39 generate_file!("ini", value, generate_from_ini);
40 }
41 if let Some(value) = file_matches.get_one::<String>("json")
42 {
43 generate_file!("json", value, generate_from_json);
44 }
45 if let Some(value) = file_matches.get_one::<String>("yaml")
46 {
47 generate_file!("yaml", value, generate_from_yaml);
48 }
49 if let Some(value) = file_matches.get_one::<String>("toml")
50 {
51 generate_file!("toml", value, generate_from_toml);
52 }
53 }
54 Some(("manual", manual_matches)) => {
55 let params = extract_manual_params(manual_matches)?;
56 if let Err(err) = generate_files(params) {
57 eprintln!("Error generating template files: {}", err);
58 } else {
59 println!("Template files generated successfully!");
60 }
61 }
62 _ => {
63 eprintln!("No valid subcommand was used. Please use '--help' for usage information.");
64 }
65 }
66
67 Ok(())
68}
69
70pub fn extract_manual_params(
72 matches: &ArgMatches,
73) -> Result<FileGenerationParams, Box<dyn Error>> {
74 let params = FileGenerationParams {
75 author: extract_param!(matches, "author"),
76 build: extract_param!(matches, "build"),
77 categories: extract_param!(matches, "categories"),
78 description: extract_param!(matches, "description"),
79 documentation: extract_param!(matches, "documentation"),
80 edition: extract_param!(matches, "edition"),
81 email: extract_param!(matches, "email"),
82 homepage: extract_param!(matches, "homepage"),
83 keywords: extract_param!(matches, "keywords"),
84 license: extract_param!(matches, "license"),
85 name: extract_param!(matches, "name"),
86 output: extract_param!(matches, "output"),
87 readme: extract_param!(matches, "readme"),
88 repository: extract_param!(matches, "repository"),
89 rustversion: extract_param!(matches, "rustversion"),
90 version: extract_param!(matches, "version"),
91 website: extract_param!(matches, "website"),
92 };
93 validate_params(¶ms)?;
94 Ok(params)
95}
96
97pub fn validate_params(
99 params: &FileGenerationParams,
100) -> Result<(), Box<dyn Error>> {
101 if params.name.is_none() {
102 return Err("The name of the library is required for manual generation.".into());
103 }
104
105 if params.output.is_none() {
106 return Err(
107 "The output directory is required for manual generation."
108 .into(),
109 );
110 }
111
112 if let Some(edition) = ¶ms.edition {
113 let valid_editions = ["2015", "2018", "2021"];
114 if !valid_editions.contains(&edition.as_str()) {
115 return Err(format!(
116 "Invalid edition: {}. Supported editions are: {}.",
117 edition,
118 valid_editions.join(", ")
119 )
120 .into());
121 }
122 }
123
124 if let Some(rustversion) = ¶ms.rustversion {
125 let version_regex = Regex::new(r"^1\.\d+\.\d+$").unwrap();
126 if !version_regex.is_match(rustversion) {
127 return Err(format!(
128 "Invalid Rust version: {}. Rust version should be in the format '1.x.y'.",
129 rustversion
130 )
131 .into());
132 }
133 }
134
135 if let Some(email) = ¶ms.email {
136 let email_regex = Regex::new(
137 r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}$",
138 )
139 .unwrap();
140 if !email_regex.is_match(email) {
141 return Err(
142 format!("Invalid email address: {}.", email).into()
143 );
144 }
145 }
146
147 if let Some(repository) = ¶ms.repository {
148 let repo_regex =
149 Regex::new(r"^(https://|git://|ssh://|git@).+\.git$")
150 .unwrap();
151 if !repo_regex.is_match(repository) {
152 return Err(format!(
153 "Invalid repository URL: {}. Repository URL should be a valid Git URL.",
154 repository
155 )
156 .into());
157 }
158 }
159
160 if let Some(homepage) = ¶ms.homepage {
161 let url_regex = Regex::new(r"^(http://|https://).+$").unwrap();
162 if !url_regex.is_match(homepage) {
163 return Err(format!(
164 "Invalid homepage URL: {}. Homepage URL should start with 'http://' or 'https://'.",
165 homepage
166 )
167 .into());
168 }
169 }
170
171 if let Some(documentation) = ¶ms.documentation {
172 let url_regex = Regex::new(r"^(http://|https://).+$").unwrap();
173 if !url_regex.is_match(documentation) {
174 return Err(format!(
175 "Invalid documentation URL: {}. Documentation URL should start with 'http://' or 'https://'.",
176 documentation
177 )
178 .into());
179 }
180 }
181
182 Ok(())
183}