Skip to main content

cargo_mate/tools/
example_gen.rs

1use super::{Tool, Result, ToolError, common_options, parse_output_format, OutputFormat};
2use clap::{Arg, ArgMatches, Command};
3use colored::*;
4use std::fs;
5use std::path::Path;
6use syn::{
7    parse_file, File, Item, ItemFn, Fields, Field, Type, PathSegment, Ident,
8    visit::Visit, spanned::Spanned,
9};
10use quote::quote;
11use proc_macro2::TokenStream;
12use serde::{Serialize, Deserialize};
13#[derive(Debug, Clone)]
14pub struct ExampleGenTool;
15#[derive(Debug, Clone, Serialize, Deserialize)]
16struct FunctionInfo {
17    name: String,
18    params: Vec<ParameterInfo>,
19    return_type: Option<String>,
20    attributes: Vec<String>,
21    documentation: Option<String>,
22    span_placeholder: String,
23}
24#[derive(Debug, Clone, Serialize, Deserialize)]
25struct ParameterInfo {
26    name: String,
27    type_info: String,
28}
29#[derive(Debug, Clone, Serialize, Deserialize)]
30struct Example {
31    title: String,
32    code: String,
33    description: Option<String>,
34    example_type: ExampleType,
35}
36#[derive(Debug, Clone, Serialize, Deserialize)]
37enum ExampleType {
38    UnitTest,
39    IntegrationTest,
40    DocTest,
41    ErrorHandling,
42}
43impl ExampleGenTool {
44    pub fn new() -> Self {
45        Self
46    }
47    fn parse_function_signatures(&self, file_path: &str) -> Result<Vec<FunctionInfo>> {
48        let content = fs::read_to_string(file_path)
49            .map_err(|e| ToolError::ExecutionFailed(
50                format!("Failed to read {}: {}", file_path, e),
51            ))?;
52        let ast = parse_file(&content)
53            .map_err(|e| ToolError::ExecutionFailed(
54                format!("Failed to parse {}: {}", file_path, e),
55            ))?;
56        let mut functions: Vec<FunctionInfo> = Vec::new();
57        struct FunctionVisitor {
58            functions: Vec<FunctionInfo>,
59        }
60        impl<'ast> Visit<'ast> for FunctionVisitor {
61            fn visit_item_fn(&mut self, node: &'ast ItemFn) {
62                if matches!(node.vis, syn::Visibility::Public(_)) {
63                    if let Some(func_info) = Self::extract_function_info(node) {
64                        self.functions.push(func_info);
65                    }
66                }
67            }
68        }
69        impl FunctionVisitor {
70            fn extract_function_info(node: &ItemFn) -> Option<FunctionInfo> {
71                let name = node.sig.ident.to_string();
72                let params = Self::extract_parameters(&node.sig.inputs);
73                let return_type = Self::extract_return_type(&node.sig.output);
74                let attributes = Self::extract_attributes(&node.attrs);
75                let documentation = Self::extract_documentation(&node.attrs);
76                Some(FunctionInfo {
77                    name,
78                    params,
79                    return_type,
80                    attributes,
81                    documentation,
82                    span_placeholder: "span_info_unavailable".to_string(),
83                })
84            }
85            fn extract_parameters(
86                inputs: &syn::punctuated::Punctuated<syn::FnArg, syn::token::Comma>,
87            ) -> Vec<ParameterInfo> {
88                let mut params = Vec::new();
89                for input in inputs {
90                    if let syn::FnArg::Receiver(_) = input {
91                        continue;
92                    }
93                    if let syn::FnArg::Typed(pat_type) = input {
94                        if let syn::Pat::Ident(pat_ident) = &*pat_type.pat {
95                            let name = pat_ident.ident.to_string();
96                            let type_info = Self::type_to_string(&*pat_type.ty);
97                            params.push(ParameterInfo { name, type_info });
98                        }
99                    }
100                }
101                params
102            }
103            fn extract_return_type(output: &syn::ReturnType) -> Option<String> {
104                match output {
105                    syn::ReturnType::Default => None,
106                    syn::ReturnType::Type(_, ty) => Some(Self::type_to_string(ty)),
107                }
108            }
109            fn extract_attributes(attrs: &[syn::Attribute]) -> Vec<String> {
110                attrs
111                    .iter()
112                    .map(|attr| {
113                        attr.path()
114                            .segments
115                            .iter()
116                            .map(|seg| seg.ident.to_string())
117                            .collect::<Vec<_>>()
118                            .join("::")
119                    })
120                    .collect()
121            }
122            fn extract_documentation(attrs: &[syn::Attribute]) -> Option<String> {
123                for attr in attrs {
124                    if let Some(seg) = attr.path().segments.first() {
125                        if seg.ident == "doc" {
126                            if let Ok(syn::Meta::NameValue(name_value)) = attr
127                                .parse_args::<syn::Meta>()
128                            {
129                                if let syn::Expr::Lit(expr_lit) = &name_value.value {
130                                    if let syn::Lit::Str(lit_str) = &expr_lit.lit {
131                                        return Some(lit_str.value().trim().to_string());
132                                    }
133                                }
134                            }
135                        }
136                    }
137                }
138                None
139            }
140            fn type_to_string(ty: &Type) -> String {
141                match ty {
142                    Type::Path(type_path) => {
143                        type_path
144                            .path
145                            .segments
146                            .iter()
147                            .map(|seg| seg.ident.to_string())
148                            .collect::<Vec<_>>()
149                            .join("::")
150                    }
151                    Type::Reference(type_ref) => {
152                        let mut result = "&".to_string();
153                        if type_ref.mutability.is_some() {
154                            result.push_str("mut ");
155                        }
156                        result.push_str(&Self::type_to_string(&*type_ref.elem));
157                        result
158                    }
159                    _ => "Unknown".to_string(),
160                }
161            }
162        }
163        let mut visitor = FunctionVisitor {
164            functions: Vec::new(),
165        };
166        syn::visit::visit_file(&mut visitor, &ast);
167        Ok(visitor.functions)
168    }
169    fn generate_function_examples(
170        &self,
171        func_info: &FunctionInfo,
172        example_types: &[String],
173    ) -> Result<Vec<Example>> {
174        let mut examples = Vec::new();
175        for example_type in example_types {
176            match example_type.as_str() {
177                "unit" => {
178                    if let Some(example) = self.create_unit_test_example(func_info)? {
179                        examples.push(example);
180                    }
181                }
182                "integration" => {
183                    if let Some(example) = self
184                        .create_integration_test_example(func_info)?
185                    {
186                        examples.push(example);
187                    }
188                }
189                "doc" => {
190                    if let Some(example) = self.create_doc_test_example(func_info)? {
191                        examples.push(example);
192                    }
193                }
194                "error-handling" => {
195                    let error_examples = self
196                        .generate_error_handling_examples(func_info)?;
197                    examples.extend(error_examples);
198                }
199                _ => {}
200            }
201        }
202        Ok(examples)
203    }
204    fn create_unit_test_example(
205        &self,
206        func_info: &FunctionInfo,
207    ) -> Result<Option<Example>> {
208        if func_info.params.is_empty() {
209            return Ok(None);
210        }
211        let mut code = format!("#[cfg(test)]\nmod tests {{\n    use super::*;\n\n");
212        code.push_str(&format!("    #[test]\n    fn test_{}() {{\n", func_info.name));
213        let param_values: Vec<String> = func_info
214            .params
215            .iter()
216            .map(|param| self.generate_parameter_value(&param.type_info))
217            .collect();
218        let param_list = func_info
219            .params
220            .iter()
221            .zip(&param_values)
222            .map(|(param, value)| format!("{}: {}", param.name, value))
223            .collect::<Vec<_>>()
224            .join(", ");
225        code.push_str(
226            &format!("        let result = {}({});\n", func_info.name, param_list),
227        );
228        if let Some(return_type) = &func_info.return_type {
229            if return_type.contains("Result") || return_type.contains("Option") {
230                code.push_str("        assert!(result.is_ok());\n");
231            } else if return_type == "bool" {
232                code.push_str("        assert!(result);\n");
233            } else if return_type.contains("Vec") || return_type.contains("HashMap") {
234                code.push_str("        assert!(!result.is_empty());\n");
235            } else {
236                code.push_str("        // Add assertions based on expected behavior\n");
237            }
238        }
239        code.push_str("    }\n");
240        code.push_str("}\n");
241        Ok(
242            Some(Example {
243                title: format!("๐Ÿงช Unit Test Example for {}", func_info.name),
244                code,
245                description: Some(
246                    format!(
247                        "Basic unit test showing how to call {} with typical parameters",
248                        func_info.name
249                    ),
250                ),
251                example_type: ExampleType::UnitTest,
252            }),
253        )
254    }
255    fn create_integration_test_example(
256        &self,
257        func_info: &FunctionInfo,
258    ) -> Result<Option<Example>> {
259        let mut code = format!(
260            "#[cfg(test)]\nmod integration_tests {{\n    use super::*;\n\n"
261        );
262        code.push_str(
263            &format!("    #[test]\n    fn test_{}_integration() {{\n", func_info.name),
264        );
265        code.push_str("        // Setup test environment\n");
266        let param_values: Vec<String> = func_info
267            .params
268            .iter()
269            .enumerate()
270            .map(|(i, param)| {
271                self.generate_integration_parameter_value(&param.type_info, i)
272            })
273            .collect();
274        let param_list = func_info
275            .params
276            .iter()
277            .zip(&param_values)
278            .map(|(param, value)| format!("{}: {}", param.name, value))
279            .collect::<Vec<_>>()
280            .join(", ");
281        code.push_str(
282            &format!("        let result = {}({});\n", func_info.name, param_list),
283        );
284        code.push_str("        // Verify the result in a broader context\n");
285        if let Some(return_type) = &func_info.return_type {
286            if return_type.contains("Result") {
287                code.push_str("        match result {\n");
288                code.push_str("            Ok(value) => {\n");
289                code.push_str("                // Verify successful operation\n");
290                code.push_str(
291                    "                assert!(true); // Replace with actual verification\n",
292                );
293                code.push_str("            }\n");
294                code.push_str(
295                    "            Err(e) => panic!(\"Integration test failed: {}\", e),\n",
296                );
297                code.push_str("        }\n");
298            } else {
299                code.push_str("        // Verify integration result\n");
300                code.push_str(
301                    "        assert!(true); // Replace with actual verification\n",
302                );
303            }
304        }
305        code.push_str("    }\n");
306        code.push_str("}\n");
307        Ok(
308            Some(Example {
309                title: format!("๐Ÿ”„ Integration Test Example for {}", func_info.name),
310                code,
311                description: Some(
312                    format!(
313                        "Integration test showing {} usage in a broader context",
314                        func_info.name
315                    ),
316                ),
317                example_type: ExampleType::IntegrationTest,
318            }),
319        )
320    }
321    fn create_doc_test_example(
322        &self,
323        func_info: &FunctionInfo,
324    ) -> Result<Option<Example>> {
325        let mut code = String::new();
326        if let Some(docs) = &func_info.documentation {
327            code.push_str(&format!("/// {}\n", docs));
328        } else {
329            code.push_str(&format!("/// Example usage of {}\n", func_info.name));
330        }
331        code.push_str("///\n");
332        code.push_str("/// ```rust\n");
333        let param_values: Vec<String> = func_info
334            .params
335            .iter()
336            .map(|param| self.generate_doc_parameter_value(&param.type_info))
337            .collect();
338        let param_list = param_values.join(", ");
339        code.push_str(
340            &format!("/// let result = {}({});\n", func_info.name, param_list),
341        );
342        if let Some(return_type) = &func_info.return_type {
343            if return_type.contains("Result") {
344                code.push_str("/// match result {\n");
345                code.push_str(
346                    "///     Ok(value) => println!(\"Success: {{:?}}\", value),\n",
347                );
348                code.push_str("///     Err(e) => eprintln!(\"Error: {{}}\", e),\n");
349                code.push_str("/// }\n");
350            } else {
351                code.push_str("/// println!(\"Result: {{:?}}\", result);\n");
352            }
353        } else {
354            code.push_str("/// // Function completed successfully\n");
355        }
356        code.push_str("/// ```\n");
357        Ok(
358            Some(Example {
359                title: format!("๐Ÿ“š Documentation Example for {}", func_info.name),
360                code,
361                description: Some(
362                    format!(
363                        "Documentation example showing typical usage of {}", func_info
364                        .name
365                    ),
366                ),
367                example_type: ExampleType::DocTest,
368            }),
369        )
370    }
371    fn generate_error_handling_examples(
372        &self,
373        func_info: &FunctionInfo,
374    ) -> Result<Vec<Example>> {
375        let mut examples = Vec::new();
376        if let Some(return_type) = &func_info.return_type {
377            if return_type.contains("Result") || return_type.contains("Option") {
378                let mut code = format!(
379                    "// Error handling example for {}\n", func_info.name
380                );
381                code.push_str("// Handle potential errors gracefully\n");
382                let param_values: Vec<String> = func_info
383                    .params
384                    .iter()
385                    .map(|param| self.generate_error_parameter_value(&param.type_info))
386                    .collect();
387                let param_list = param_values.join(", ");
388                if return_type.contains("Result") {
389                    code.push_str(
390                        &format!("match {}({}) {{\n", func_info.name, param_list),
391                    );
392                    code.push_str("    Ok(result) => {\n");
393                    code.push_str("        println!(\"Success: {{:?}}\", result);\n");
394                    code.push_str("        // Process successful result\n");
395                    code.push_str("    }\n");
396                    code.push_str("    Err(error) => {\n");
397                    code.push_str(
398                        "        eprintln!(\"Operation failed: {{}}\", error);\n",
399                    );
400                    code.push_str("        // Handle error appropriately\n");
401                    code.push_str("        match error {\n");
402                    code.push_str("            // Handle specific error types\n");
403                    code.push_str("            _ => {\n");
404                    code.push_str("                // Fallback error handling\n");
405                    code.push_str("                std::process::exit(1);\n");
406                    code.push_str("            }\n");
407                    code.push_str("        }\n");
408                    code.push_str("    }\n");
409                    code.push_str("}\n");
410                } else if return_type.contains("Option") {
411                    code.push_str(
412                        &format!(
413                            "if let Some(result) = {}({}) {{\n", func_info.name,
414                            param_list
415                        ),
416                    );
417                    code.push_str("    println!(\"Success: {{:?}}\", result);\n");
418                    code.push_str("    // Process successful result\n");
419                    code.push_str("} else {\n");
420                    code.push_str("    eprintln!(\"Operation returned None\");\n");
421                    code.push_str("    // Handle None case\n");
422                    code.push_str("}\n");
423                }
424                examples
425                    .push(Example {
426                        title: format!(
427                            "โš ๏ธ Error Handling Example for {}", func_info.name
428                        ),
429                        code,
430                        description: Some(
431                            format!(
432                                "Comprehensive error handling patterns for {}", func_info
433                                .name
434                            ),
435                        ),
436                        example_type: ExampleType::ErrorHandling,
437                    });
438            }
439        }
440        Ok(examples)
441    }
442    fn generate_parameter_value(&self, param_type: &str) -> String {
443        match param_type {
444            "i32" | "i64" | "u32" | "u64" | "isize" | "usize" => "42".to_string(),
445            "String" | "&str" => "\"example\"".to_string(),
446            "bool" => "true".to_string(),
447            "f32" | "f64" => "3.14".to_string(),
448            "Vec<T>" => "vec![item1, item2]".to_string(),
449            "Option<T>" => "Some(value)".to_string(),
450            "Result<T, E>" => "Ok(value)".to_string(),
451            _ => format!("{}::default()", param_type),
452        }
453    }
454    fn generate_integration_parameter_value(
455        &self,
456        param_type: &str,
457        index: usize,
458    ) -> String {
459        match param_type {
460            "i32" | "i64" | "u32" | "u64" | "isize" | "usize" => {
461                format!("test_value_{}", index)
462            }
463            "String" | "&str" => format!("\"test_input_{}\"", index),
464            "bool" => "false".to_string(),
465            "f32" | "f64" => format!("{}.5", index + 1),
466            "Vec<T>" => format!("vec![test_item_{}]", index),
467            "Option<T>" => format!("Some(test_value_{})", index),
468            "Result<T, E>" => format!("Ok(test_result_{})", index),
469            _ => format!("test_{}", index),
470        }
471    }
472    fn generate_doc_parameter_value(&self, param_type: &str) -> String {
473        match param_type {
474            "i32" | "i64" | "u32" | "u64" | "isize" | "usize" => "123".to_string(),
475            "String" | "&str" => "\"hello world\"".to_string(),
476            "bool" => "true".to_string(),
477            "f32" | "f64" => "2.5".to_string(),
478            "Vec<T>" => "vec![item1, item2]".to_string(),
479            "Option<T>" => "Some(value)".to_string(),
480            "Result<T, E>" => "Ok(result)".to_string(),
481            _ => "value".to_string(),
482        }
483    }
484    fn generate_error_parameter_value(&self, param_type: &str) -> String {
485        match param_type {
486            "i32" | "i64" | "u32" | "u64" | "isize" | "usize" => "0".to_string(),
487            "String" | "&str" => "\"\"".to_string(),
488            "bool" => "false".to_string(),
489            "f32" | "f64" => "0.0".to_string(),
490            "Vec<T>" => "vec![]".to_string(),
491            "Option<T>" => "None".to_string(),
492            "Result<T, E>" => "Err(error)".to_string(),
493            _ => "invalid_value".to_string(),
494        }
495    }
496    fn format_examples_as_rust(&self, examples: &[Example]) -> Result<String> {
497        let mut code = String::new();
498        for (i, example) in examples.iter().enumerate() {
499            if i > 0 {
500                code.push_str("\n\n");
501            }
502            code.push_str(&format!("// {}\n", example.title));
503            if let Some(desc) = &example.description {
504                code.push_str(&format!("// {}\n", desc));
505            }
506            code.push_str(&example.code);
507        }
508        Ok(code)
509    }
510    fn format_examples_as_markdown(&self, examples: &[Example]) -> Result<String> {
511        let mut markdown = String::new();
512        for example in examples {
513            markdown.push_str(&format!("## {}\n\n", example.title));
514            if let Some(description) = &example.description {
515                markdown.push_str(&format!("{}\n\n", description));
516            }
517            markdown.push_str("```rust\n");
518            markdown.push_str(&example.code);
519            markdown.push_str("\n```\n\n");
520        }
521        Ok(markdown)
522    }
523}
524impl Tool for ExampleGenTool {
525    fn name(&self) -> &'static str {
526        "example-gen"
527    }
528    fn description(&self) -> &'static str {
529        "Generate runnable examples from function signatures"
530    }
531    fn command(&self) -> Command {
532        Command::new(self.name())
533            .about(self.description())
534            .long_about(
535                "Automatically generate runnable examples from function signatures, helping developers understand how to use APIs. Creates unit tests, integration tests, documentation examples, and error handling patterns.",
536            )
537            .args(
538                &[
539                    Arg::new("input")
540                        .long("input")
541                        .short('i')
542                        .help("Input Rust file or directory to analyze")
543                        .required(true),
544                    Arg::new("function")
545                        .long("function")
546                        .short('f')
547                        .help("Specific function to generate examples for"),
548                    Arg::new("type")
549                        .long("type")
550                        .short('t')
551                        .help("Example types: unit, integration, doc, error-handling")
552                        .default_value("unit,doc"),
553                    Arg::new("output")
554                        .long("output")
555                        .short('o')
556                        .help("Output directory for generated examples")
557                        .default_value("examples/generated/"),
558                    Arg::new("format")
559                        .long("format")
560                        .help("Output format: rust, markdown, json")
561                        .default_value("rust"),
562                    Arg::new("include-private")
563                        .long("include-private")
564                        .help("Include examples for private functions")
565                        .action(clap::ArgAction::SetTrue),
566                    Arg::new("with-tests")
567                        .long("with-tests")
568                        .help("Generate corresponding test files")
569                        .action(clap::ArgAction::SetTrue),
570                    Arg::new("context")
571                        .long("context")
572                        .help("Include usage context and dependencies")
573                        .action(clap::ArgAction::SetTrue),
574                    Arg::new("validate")
575                        .long("validate")
576                        .help("Validate that generated examples compile")
577                        .action(clap::ArgAction::SetTrue),
578                ],
579            )
580            .args(&common_options())
581    }
582    fn execute(&self, matches: &ArgMatches) -> Result<()> {
583        let input = matches.get_one::<String>("input").unwrap();
584        let function_filter = matches.get_one::<String>("function");
585        let example_types: Vec<String> = matches
586            .get_one::<String>("type")
587            .unwrap()
588            .split(',')
589            .map(|s| s.trim().to_string())
590            .collect();
591        let output = matches.get_one::<String>("output").unwrap();
592        let format = matches.get_one::<String>("format").unwrap();
593        let dry_run = matches.get_flag("dry-run");
594        let verbose = matches.get_flag("verbose");
595        let validate = matches.get_flag("validate");
596        let output_format = parse_output_format(matches);
597        println!(
598            "๐Ÿ“š {} - {}", "CargoMate ExampleGen".bold().blue(), self.description()
599            .cyan()
600        );
601        if !Path::new(input).exists() {
602            return Err(
603                ToolError::InvalidArguments(format!("Input not found: {}", input)),
604            );
605        }
606        if !dry_run {
607            fs::create_dir_all(output)
608                .map_err(|e| ToolError::ExecutionFailed(
609                    format!("Failed to create output directory: {}", e),
610                ))?;
611        }
612        let mut all_examples = Vec::new();
613        if Path::new(input).is_dir() {
614            for entry in fs::read_dir(input)? {
615                let entry = entry?;
616                let path = entry.path();
617                if path.is_file() && path.extension().unwrap_or_default() == "rs" {
618                    let functions = self
619                        .parse_function_signatures(&path.to_string_lossy())?;
620                    for func_info in functions {
621                        if let Some(filter) = function_filter {
622                            if func_info.name != *filter {
623                                continue;
624                            }
625                        }
626                        let examples = self
627                            .generate_function_examples(&func_info, &example_types)?;
628                        all_examples.extend(examples);
629                    }
630                }
631            }
632        } else {
633            let functions = self.parse_function_signatures(input)?;
634            for func_info in functions {
635                if let Some(filter) = function_filter {
636                    if func_info.name != *filter {
637                        continue;
638                    }
639                }
640                let examples = self
641                    .generate_function_examples(&func_info, &example_types)?;
642                all_examples.extend(examples);
643            }
644        }
645        if all_examples.is_empty() {
646            println!(
647                "{}", "No examples generated. Check input file or function filter."
648                .yellow()
649            );
650            return Ok(());
651        }
652        if verbose {
653            println!(
654                "   ๐Ÿ“Š Generated {} examples from {} functions", all_examples.len(),
655                all_examples.len() / example_types.len()
656            );
657        }
658        let output_content = match format.as_str() {
659            "rust" => self.format_examples_as_rust(&all_examples)?,
660            "markdown" => self.format_examples_as_markdown(&all_examples)?,
661            "json" => serde_json::to_string_pretty(&all_examples).unwrap(),
662            _ => {
663                return Err(
664                    ToolError::InvalidArguments(
665                        format!("Unsupported format: {}", format),
666                    ),
667                );
668            }
669        };
670        let output_file = format!("{}/generated_examples.{}", output, format);
671        match output_format {
672            OutputFormat::Human => {
673                println!("  โœ… Generated {} examples", all_examples.len());
674                println!("     โ†’ {}", output_file.cyan());
675                if validate {
676                    println!("  โœ… Validation enabled - checking example compilation");
677                }
678                if dry_run {
679                    println!("   ๐Ÿ“‹ {}", "Generated content preview:".bold());
680                    println!("   {}", "โ”€".repeat(50));
681                    for line in output_content.lines().take(10) {
682                        println!("   {}", line);
683                    }
684                    if output_content.lines().count() > 10 {
685                        println!("   ... (truncated)");
686                    }
687                } else {
688                    fs::write(&output_file, &output_content)
689                        .map_err(|e| ToolError::ExecutionFailed(
690                            format!("Failed to write {}: {}", output_file, e),
691                        ))?;
692                    println!("  ๐Ÿ’พ File written successfully");
693                }
694            }
695            OutputFormat::Json => {
696                let result = serde_json::json!(
697                    { "input" : input, "output" : output_file, "examples_generated" :
698                    all_examples.len(), "format" : format, "example_types" :
699                    example_types, "content_preview" : output_content.lines().take(5)
700                    .collect::< Vec < _ >> ().join("\n") }
701                );
702                println!("{}", serde_json::to_string_pretty(& result).unwrap());
703            }
704            OutputFormat::Table => {
705                println!("{:<30} {:<15} {:<20}", "Function", "Examples", "Types");
706                println!("{}", "โ”€".repeat(70));
707                let mut example_counts = std::collections::HashMap::new();
708                for example in &all_examples {
709                    let count = example_counts.entry(example.title.clone()).or_insert(0);
710                    *count += 1;
711                }
712                for (title, count) in example_counts {
713                    println!(
714                        "{:<30} {:<15} {:<20}", title, count, example_types.join(",")
715                    );
716                }
717            }
718        }
719        println!("\n๐ŸŽ‰ Example generation completed!");
720        Ok(())
721    }
722}
723impl Default for ExampleGenTool {
724    fn default() -> Self {
725        Self::new()
726    }
727}