1use clap::Parser;
2use log::info;
3use std::io;
4use std::path::Path;
5use std::time::Instant;
6
7pub mod cli;
8pub mod file_utils;
9pub mod markdown;
10pub mod tree;
11
12use cli::Args;
13use file_utils::{collect_files, confirm_processing, confirm_overwrite};
14use markdown::generate_markdown;
15use tree::{build_file_tree, print_tree};
16
17
18pub fn run() -> io::Result<()> {
19 env_logger::init();
20 let args = Args::parse();
21 let start_time = Instant::now();
22
23 let base_path = Path::new(&args.input);
24
25 if !base_path.exists() || !base_path.is_dir() {
27
28 eprintln!("Error: The specified input directory '{}' does not exist or is not a directory.", args.input);
30 return Ok(());
31 }
32
33 if Path::new(&args.output).exists() {
35 if !confirm_overwrite(&args.output)? {
37 println!("Operation cancelled.");
38 return Ok(());
39 }
40 }
41
42 info!("Starting file collection...");
44 let files = collect_files(base_path, &args.filter, &args.ignore)?;
45 info!("Found {} files to process.", files.len());
46
47 let file_tree = build_file_tree(&files, base_path);
49
50 if args.preview {
52 println!("\n# File Tree Structure (Preview)\n");
53 print_tree(&file_tree, 0);
54 return Ok(());
55 }
56
57 if !confirm_processing(files.len())? {
59 println!("Operation cancelled.");
60 return Ok(());
61 }
62
63 generate_markdown(
65 &args.output,
66 &args.input,
67 &args.filter,
68 &args.ignore,
69 &file_tree,
70 &files,
71 base_path,
72 args.line_numbers,
73 )?;
74
75 let duration = start_time.elapsed();
76 println!("Documentation created successfully: {}", args.output);
77 println!("Processing time: {:.2?}", duration);
78
79 Ok(())
80}