1use std::io::{self, Write};
4
5use crate::application::{
6 GenerateOptions, GenerateUseCase, StatsOptions, StatsUseCase, ValidateOptions, ValidateUseCase,
7 WikiOptions, WikiUseCase,
8};
9use crate::cli::args::{Cli, Commands, GenerateArgs, StatsArgs, ValidateArgs, WikiArgs};
10use crate::domain::Severity;
11use crate::error::Result;
12use crate::infrastructure::RealFileSystem;
13
14pub fn run(cli: Cli) -> Result<i32> {
20 match cli.command {
21 Commands::Generate(args) => handle_generate(args, cli.verbose),
22 Commands::Wiki(args) => handle_wiki(args, cli.verbose),
23 Commands::Validate(args) => handle_validate(args, cli.verbose),
24 Commands::Stats(args) => handle_stats(args, cli.verbose),
25 }
26}
27
28fn handle_generate(args: GenerateArgs, verbose: bool) -> Result<i32> {
29 let fs = RealFileSystem::new();
30 let use_case = GenerateUseCase::new(fs);
31
32 let options = GenerateOptions::new(&args.input)
33 .with_output(&args.output)
34 .with_title(&args.title)
35 .with_theme(args.theme.into())
36 .with_pattern(&args.pattern);
37
38 if verbose {
39 eprintln!("Scanning for ADRs in: {}", args.input);
40 }
41
42 let result = use_case.execute(&options)?;
43
44 if result.has_errors() {
46 eprintln!("\nWarnings:");
47 for (path, error) in &result.parse_errors {
48 eprintln!(" {} - {}", path.display(), error);
49 }
50 }
51
52 println!(
53 "Generated {} with {} ADRs",
54 result.output_path, result.adr_count
55 );
56
57 Ok(0)
58}
59
60fn handle_wiki(args: WikiArgs, verbose: bool) -> Result<i32> {
61 let fs = RealFileSystem::new();
62 let use_case = WikiUseCase::new(fs);
63
64 let mut options = WikiOptions::new(&args.input)
65 .with_output_dir(&args.output)
66 .with_pattern(&args.pattern);
67
68 if let Some(url) = &args.pages_url {
69 options = options.with_pages_url(url);
70 }
71
72 if verbose {
73 eprintln!("Scanning for ADRs in: {}", args.input);
74 }
75
76 let result = use_case.execute(&options)?;
77
78 if result.has_errors() {
80 eprintln!("\nWarnings:");
81 for (path, error) in &result.parse_errors {
82 eprintln!(" {} - {}", path.display(), error);
83 }
84 }
85
86 println!(
87 "Generated {} wiki files in {} from {} ADRs",
88 result.generated_files.len(),
89 result.output_dir,
90 result.adr_count
91 );
92
93 if verbose {
94 eprintln!("\nGenerated files:");
95 for file in &result.generated_files {
96 eprintln!(" {file}");
97 }
98 }
99
100 Ok(0)
101}
102
103fn handle_validate(args: ValidateArgs, verbose: bool) -> Result<i32> {
104 let fs = RealFileSystem::new();
105 let use_case = ValidateUseCase::new(fs);
106
107 let options = ValidateOptions::new(&args.input)
108 .with_pattern(&args.pattern)
109 .with_strict(args.strict);
110
111 if verbose {
112 eprintln!("Validating ADRs in: {}", args.input);
113 }
114
115 let result = use_case.execute(&options)?;
116
117 for (path, error) in &result.parse_errors {
119 eprintln!("ERROR: {} - {}", path.display(), error);
120 }
121
122 let mut stdout = io::stdout();
124 for (path, issue) in result.all_issues() {
125 let prefix = match issue.severity {
126 Severity::Error => "ERROR",
127 Severity::Warning => "WARNING",
128 };
129 let _ = writeln!(
130 stdout,
131 "{}: {} - {} [{}]",
132 prefix,
133 path.display(),
134 issue.message,
135 issue.rule
136 );
137 }
138
139 println!(
141 "\nValidation complete: {} errors, {} warnings",
142 result.total_errors, result.total_warnings
143 );
144
145 if result.passed {
146 println!("All checks passed.");
147 Ok(0)
148 } else {
149 println!("Validation failed.");
150 Ok(1)
151 }
152}
153
154fn handle_stats(args: StatsArgs, verbose: bool) -> Result<i32> {
155 let fs = RealFileSystem::new();
156 let use_case = StatsUseCase::new(fs);
157
158 let options = StatsOptions::new(&args.input)
159 .with_pattern(&args.pattern)
160 .with_format(args.format.into());
161
162 if verbose {
163 eprintln!("Computing statistics for ADRs in: {}", args.input);
164 }
165
166 let result = use_case.execute(&options)?;
167
168 if result.has_errors() {
170 eprintln!("\nWarnings:");
171 for (path, error) in &result.parse_errors {
172 eprintln!(" {} - {}", path.display(), error);
173 }
174 eprintln!();
175 }
176
177 println!("{}", result.output);
178
179 Ok(0)
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185
186 #[test]
191 fn test_handler_functions_exist() {
192 let _: fn(GenerateArgs, bool) -> Result<i32> = handle_generate;
195 let _: fn(WikiArgs, bool) -> Result<i32> = handle_wiki;
196 let _: fn(ValidateArgs, bool) -> Result<i32> = handle_validate;
197 let _: fn(StatsArgs, bool) -> Result<i32> = handle_stats;
198 }
199}