Skip to main content

cargo_mate/tools/
trait_explorer.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 std::collections::HashMap;
7use syn::{
8    parse_file, File, Item, ItemTrait, ItemImpl, TraitItem, visit::Visit,
9    spanned::Spanned,
10};
11use quote::quote;
12use proc_macro2::TokenStream;
13#[derive(Debug, Clone)]
14pub struct TraitExplorerTool;
15#[derive(Debug, Clone)]
16struct TraitDefinition {
17    name: String,
18    methods: Vec<TraitMethod>,
19    supertraits: Vec<String>,
20    visibility: String,
21    attributes: Vec<String>,
22    file_path: String,
23    line_number: usize,
24}
25#[derive(Debug, Clone)]
26struct TraitMethod {
27    name: String,
28    signature: String,
29    is_required: bool,
30    has_default_implementation: bool,
31}
32#[derive(Debug, Clone)]
33struct TraitImplementation {
34    trait_name: String,
35    target_type: String,
36    methods: Vec<ImplMethod>,
37    file_path: String,
38    line_number: usize,
39    is_foreign: bool,
40}
41#[derive(Debug, Clone)]
42struct ImplMethod {
43    name: String,
44    is_override: bool,
45}
46#[derive(Debug, Clone)]
47struct TraitAnalysis {
48    trait_definitions: Vec<TraitDefinition>,
49    trait_implementations: Vec<TraitImplementation>,
50    trait_usage_patterns: HashMap<String, Vec<String>>,
51    orphan_rules_violations: Vec<String>,
52    missing_implementations: Vec<String>,
53}
54#[derive(Debug, Clone)]
55struct TraitGraph {
56    nodes: Vec<String>,
57    edges: Vec<(String, String)>,
58}
59#[derive(Debug, Clone)]
60struct TraitSuggestion {
61    trait_name: String,
62    target_type: String,
63    reason: String,
64    confidence: f64,
65}
66impl TraitExplorerTool {
67    pub fn new() -> Self {
68        Self
69    }
70    fn discover_trait_definitions(
71        &self,
72        source_path: &str,
73    ) -> Result<Vec<TraitDefinition>> {
74        let mut traits = Vec::new();
75        self.analyze_directory_for_traits(source_path, &mut traits)?;
76        Ok(traits)
77    }
78    fn analyze_directory_for_traits(
79        &self,
80        dir_path: &str,
81        traits: &mut Vec<TraitDefinition>,
82    ) -> Result<()> {
83        let entries = fs::read_dir(dir_path)
84            .map_err(|e| ToolError::ExecutionFailed(
85                format!("Failed to read directory {}: {}", dir_path, e),
86            ))?;
87        for entry in entries {
88            let entry = entry?;
89            let path = entry.path();
90            if path.is_dir() {
91                self.analyze_directory_for_traits(&path.to_string_lossy(), traits)?;
92            } else if let Some(ext) = path.extension() {
93                if ext == "rs" {
94                    self.analyze_file_for_traits(&path, traits)?;
95                }
96            }
97        }
98        Ok(())
99    }
100    fn analyze_file_for_traits(
101        &self,
102        file_path: &Path,
103        traits: &mut Vec<TraitDefinition>,
104    ) -> Result<()> {
105        let content = fs::read_to_string(file_path)?;
106        let ast = parse_file(&content)?;
107        struct TraitVisitor<'a> {
108            traits: &'a mut Vec<TraitDefinition>,
109            current_file: String,
110        }
111        impl<'a> Visit<'_> for TraitVisitor<'a> {
112            fn visit_item_trait(&mut self, node: &ItemTrait) {
113                let trait_def = TraitDefinition {
114                    name: node.ident.to_string(),
115                    methods: Self::extract_trait_methods(&node.items),
116                    supertraits: Self::extract_supertraits(&node.supertraits),
117                    visibility: if matches!(node.vis, syn::Visibility::Public(_)) {
118                        "pub".to_string()
119                    } else {
120                        "private".to_string()
121                    },
122                    attributes: Self::extract_attributes(&node.attrs),
123                    file_path: self.current_file.clone(),
124                    line_number: 0,
125                };
126                self.traits.push(trait_def);
127            }
128        }
129        impl TraitVisitor<'_> {
130            fn extract_trait_methods(items: &[TraitItem]) -> Vec<TraitMethod> {
131                let mut methods = Vec::new();
132                for item in items {
133                    if let TraitItem::Fn(method) = item {
134                        let name = method.sig.ident.to_string();
135                        let signature = Self::format_method_signature(&method.sig);
136                        let (is_required, has_default) = match &method.default {
137                            Some(_) => (false, true),
138                            None => (true, false),
139                        };
140                        methods
141                            .push(TraitMethod {
142                                name,
143                                signature,
144                                is_required,
145                                has_default_implementation: has_default,
146                            });
147                    }
148                }
149                methods
150            }
151            fn extract_supertraits(
152                supertraits: &syn::punctuated::Punctuated<
153                    syn::TypeParamBound,
154                    syn::token::Plus,
155                >,
156            ) -> Vec<String> {
157                let mut traits = Vec::new();
158                for bound in supertraits {
159                    if let syn::TypeParamBound::Trait(trait_bound) = bound {
160                        let trait_name = trait_bound
161                            .path
162                            .segments
163                            .iter()
164                            .map(|seg| seg.ident.to_string())
165                            .collect::<Vec<_>>()
166                            .join("::");
167                        traits.push(trait_name);
168                    }
169                }
170                traits
171            }
172            fn extract_attributes(attrs: &[syn::Attribute]) -> Vec<String> {
173                attrs
174                    .iter()
175                    .map(|attr| {
176                        attr.path()
177                            .segments
178                            .iter()
179                            .map(|seg| seg.ident.to_string())
180                            .collect::<Vec<_>>()
181                            .join("::")
182                    })
183                    .collect()
184            }
185            fn format_method_signature(sig: &syn::Signature) -> String {
186                let params = sig
187                    .inputs
188                    .iter()
189                    .filter_map(|arg| {
190                        match arg {
191                            syn::FnArg::Receiver(_) => Some("self".to_string()),
192                            syn::FnArg::Typed(pat_type) => {
193                                if let syn::Pat::Ident(pat_ident) = &*pat_type.pat {
194                                    Some(
195                                        format!(
196                                            "{}: {}", pat_ident.ident, Self::type_to_string(&* pat_type
197                                            .ty)
198                                        ),
199                                    )
200                                } else {
201                                    None
202                                }
203                            }
204                        }
205                    })
206                    .collect::<Vec<_>>()
207                    .join(", ");
208                let return_type = match &sig.output {
209                    syn::ReturnType::Default => String::new(),
210                    syn::ReturnType::Type(_, ty) => {
211                        format!(" -> {}", Self::type_to_string(ty))
212                    }
213                };
214                format!("fn {}({}){}", sig.ident, params, return_type)
215            }
216            fn type_to_string(ty: &syn::Type) -> String {
217                match ty {
218                    syn::Type::Path(type_path) => {
219                        type_path
220                            .path
221                            .segments
222                            .iter()
223                            .map(|seg| seg.ident.to_string())
224                            .collect::<Vec<_>>()
225                            .join("::")
226                    }
227                    syn::Type::Reference(type_ref) => {
228                        let mut result = "&".to_string();
229                        if type_ref.mutability.is_some() {
230                            result.push_str("mut ");
231                        }
232                        result.push_str(&Self::type_to_string(&*type_ref.elem));
233                        result
234                    }
235                    _ => "Unknown".to_string(),
236                }
237            }
238        }
239        let mut visitor = TraitVisitor {
240            traits,
241            current_file: file_path.to_string_lossy().to_string(),
242        };
243        syn::visit::visit_file(&mut visitor, &ast);
244        Ok(())
245    }
246    fn discover_trait_implementations(
247        &self,
248        source_path: &str,
249    ) -> Result<Vec<TraitImplementation>> {
250        let mut implementations = Vec::new();
251        self.analyze_directory_for_implementations(source_path, &mut implementations)?;
252        Ok(implementations)
253    }
254    fn analyze_directory_for_implementations(
255        &self,
256        dir_path: &str,
257        implementations: &mut Vec<TraitImplementation>,
258    ) -> Result<()> {
259        let entries = fs::read_dir(dir_path)
260            .map_err(|e| ToolError::ExecutionFailed(
261                format!("Failed to read directory {}: {}", dir_path, e),
262            ))?;
263        for entry in entries {
264            let entry = entry?;
265            let path = entry.path();
266            if path.is_dir() {
267                self.analyze_directory_for_implementations(
268                    &path.to_string_lossy(),
269                    implementations,
270                )?;
271            } else if let Some(ext) = path.extension() {
272                if ext == "rs" {
273                    self.analyze_file_for_implementations(&path, implementations)?;
274                }
275            }
276        }
277        Ok(())
278    }
279    fn analyze_file_for_implementations(
280        &self,
281        file_path: &Path,
282        implementations: &mut Vec<TraitImplementation>,
283    ) -> Result<()> {
284        let content = fs::read_to_string(file_path)?;
285        let ast = parse_file(&content)?;
286        struct ImplVisitor<'a> {
287            implementations: &'a mut Vec<TraitImplementation>,
288            current_file: String,
289        }
290        impl<'a> Visit<'_> for ImplVisitor<'a> {
291            fn visit_item_impl(&mut self, node: &ItemImpl) {
292                if let Some((_, trait_path, _)) = &node.trait_ {
293                    let trait_name = trait_path
294                        .segments
295                        .iter()
296                        .map(|seg| seg.ident.to_string())
297                        .collect::<Vec<_>>()
298                        .join("::");
299                    let target_type = Self::extract_target_type(&node.self_ty);
300                    let methods = node
301                        .items
302                        .iter()
303                        .filter_map(|item| {
304                            match item {
305                                syn::ImplItem::Fn(method) => {
306                                    Some(ImplMethod {
307                                        name: method.sig.ident.to_string(),
308                                        is_override: method
309                                            .attrs
310                                            .iter()
311                                            .any(|attr| {
312                                                attr.path()
313                                                    .segments
314                                                    .iter()
315                                                    .any(|seg| seg.ident == "override")
316                                            }),
317                                    })
318                                }
319                                _ => None,
320                            }
321                        })
322                        .collect();
323                    let impl_info = TraitImplementation {
324                        trait_name,
325                        target_type,
326                        methods,
327                        file_path: self.current_file.clone(),
328                        line_number: 0,
329                        is_foreign: false,
330                    };
331                    self.implementations.push(impl_info);
332                }
333            }
334        }
335        impl ImplVisitor<'_> {
336            fn extract_target_type(ty: &syn::Type) -> String {
337                match ty {
338                    syn::Type::Path(type_path) => {
339                        type_path
340                            .path
341                            .segments
342                            .iter()
343                            .map(|seg| seg.ident.to_string())
344                            .collect::<Vec<_>>()
345                            .join("::")
346                    }
347                    _ => "Unknown".to_string(),
348                }
349            }
350        }
351        let mut visitor = ImplVisitor {
352            implementations,
353            current_file: file_path.to_string_lossy().to_string(),
354        };
355        syn::visit::visit_file(&mut visitor, &ast);
356        Ok(())
357    }
358    fn analyze_trait_usage(
359        &self,
360        implementations: &[TraitImplementation],
361    ) -> Result<HashMap<String, Vec<String>>> {
362        let mut usage_patterns = HashMap::new();
363        for impl_info in implementations {
364            usage_patterns
365                .entry(impl_info.trait_name.clone())
366                .or_insert_with(Vec::new)
367                .push(impl_info.target_type.clone());
368        }
369        Ok(usage_patterns)
370    }
371    fn find_missing_implementations(
372        &self,
373        traits: &[TraitDefinition],
374        implementations: &[TraitImplementation],
375    ) -> Vec<String> {
376        let mut missing = Vec::new();
377        let implemented_traits: HashMap<String, Vec<String>> = implementations
378            .iter()
379            .fold(
380                HashMap::new(),
381                |mut acc, impl_info| {
382                    acc.entry(impl_info.trait_name.clone())
383                        .or_insert_with(Vec::new)
384                        .push(impl_info.target_type.clone());
385                    acc
386                },
387            );
388        for trait_def in traits {
389            if let Some(implementors) = implemented_traits.get(&trait_def.name) {
390                if implementors.is_empty() {
391                    missing
392                        .push(
393                            format!("Trait '{}' has no implementations", trait_def.name),
394                        );
395                }
396            } else {
397                missing
398                    .push(format!("Trait '{}' has no implementations", trait_def.name));
399            }
400        }
401        missing
402    }
403    fn generate_trait_documentation(
404        &self,
405        traits: &[TraitDefinition],
406        implementations: &[TraitImplementation],
407    ) -> Result<String> {
408        let mut docs = String::from("# Trait Implementation Analysis\n\n");
409        docs.push_str(
410            &format!(
411                "Generated on: {}\n\n", chrono::Utc::now().format("%Y-%m-%d %H:%M:%S")
412            ),
413        );
414        docs.push_str("## šŸ“Š Overview\n\n");
415        docs.push_str(&format!("- **Total Traits**: {}\n", traits.len()));
416        docs.push_str(
417            &format!("- **Total Implementations**: {}\n", implementations.len()),
418        );
419        let trait_usage: HashMap<String, usize> = implementations
420            .iter()
421            .fold(
422                HashMap::new(),
423                |mut acc, impl_info| {
424                    *acc.entry(impl_info.trait_name.clone()).or_insert(0) += 1;
425                    acc
426                },
427            );
428        let most_used_trait = trait_usage
429            .iter()
430            .max_by_key(|(_, count)| *count)
431            .map(|(name, _)| name.as_str())
432            .unwrap_or("None");
433        docs.push_str(&format!("- **Most Implemented Trait**: {}\n\n", most_used_trait));
434        docs.push_str("## šŸŽÆ Trait Implementations\n\n");
435        for trait_def in traits {
436            docs.push_str(&format!("### `{}` Trait\n", trait_def.name));
437            docs.push_str(&format!("**File:** `{}`\n", trait_def.file_path));
438            docs.push_str(&format!("**Visibility:** {}\n\n", trait_def.visibility));
439            if !trait_def.supertraits.is_empty() {
440                docs.push_str("**Supertraits:**\n");
441                for supertrait in &trait_def.supertraits {
442                    docs.push_str(&format!("- `{}`\n", supertrait));
443                }
444                docs.push_str("\n");
445            }
446            docs.push_str("**Methods:**\n");
447            for method in &trait_def.methods {
448                let required = if method.is_required { "Required" } else { "Optional" };
449                let default = if method.has_default_implementation {
450                    " (has default)"
451                } else {
452                    ""
453                };
454                docs.push_str(
455                    &format!("- `{}` - {}{}\n", method.signature, required, default),
456                );
457            }
458            docs.push_str("\n");
459            let trait_implementations: Vec<&TraitImplementation> = implementations
460                .iter()
461                .filter(|impl_info| impl_info.trait_name == trait_def.name)
462                .collect();
463            if !trait_implementations.is_empty() {
464                docs.push_str("**Known Implementations:**\n");
465                for impl_info in &trait_implementations {
466                    docs.push_str(
467                        &format!(
468                            "- `{}` in `{}`\n", impl_info.target_type, impl_info
469                            .file_path
470                        ),
471                    );
472                }
473            } else {
474                docs.push_str("**No implementations found**\n");
475            }
476            docs.push_str("\n");
477        }
478        let missing = self.find_missing_implementations(traits, implementations);
479        if !missing.is_empty() {
480            docs.push_str("## āš ļø Missing Implementations\n\n");
481            for issue in &missing {
482                docs.push_str(&format!("- {}\n", issue));
483            }
484            docs.push_str("\n");
485        }
486        Ok(docs)
487    }
488    fn generate_trait_visualization(
489        &self,
490        traits: &[TraitDefinition],
491        implementations: &[TraitImplementation],
492        format: &str,
493    ) -> Result<String> {
494        match format {
495            "mermaid" => self.generate_mermaid_graph(traits, implementations),
496            "dot" => self.generate_dot_graph(traits, implementations),
497            _ => {
498                Err(
499                    ToolError::InvalidArguments(
500                        format!("Unsupported visualization format: {}", format),
501                    ),
502                )
503            }
504        }
505    }
506    fn generate_mermaid_graph(
507        &self,
508        traits: &[TraitDefinition],
509        implementations: &[TraitImplementation],
510    ) -> Result<String> {
511        let mut mermaid = String::from("```mermaid\ngraph TD\n");
512        for trait_def in traits {
513            mermaid
514                .push_str(
515                    &format!(
516                        "    T{}[\"Trait: {}\"]\n", trait_def.name.replace("::", "_"),
517                        trait_def.name
518                    ),
519                );
520        }
521        for impl_info in implementations {
522            let trait_node = impl_info.trait_name.replace("::", "_");
523            let type_node = impl_info.target_type.replace("::", "_");
524            mermaid
525                .push_str(
526                    &format!(
527                        "    T{} --> I{}[\"Impl: {}\"]\n", trait_node, type_node,
528                        impl_info.target_type
529                    ),
530                );
531        }
532        for trait_def in traits {
533            for supertrait in &trait_def.supertraits {
534                let super_node = supertrait.replace("::", "_");
535                let trait_node = trait_def.name.replace("::", "_");
536                mermaid
537                    .push_str(
538                        &format!(
539                            "    T{} --> T{}[\"Supertrait: {}\"]\n", trait_node,
540                            super_node, supertrait
541                        ),
542                    );
543            }
544        }
545        mermaid.push_str("```\n");
546        Ok(mermaid)
547    }
548    fn generate_dot_graph(
549        &self,
550        traits: &[TraitDefinition],
551        implementations: &[TraitImplementation],
552    ) -> Result<String> {
553        let mut dot = String::from("digraph TraitGraph {\n");
554        dot.push_str("    rankdir=LR;\n");
555        dot.push_str("    node [shape=box];\n\n");
556        for trait_def in traits {
557            dot.push_str(
558                &format!(
559                    "    \"{}\" [label=\"Trait: {}\", fillcolor=lightblue, style=filled];\n",
560                    trait_def.name, trait_def.name
561                ),
562            );
563        }
564        for impl_info in implementations {
565            dot.push_str(
566                &format!(
567                    "    \"{}\" [label=\"Impl: {}\"];\n", impl_info.target_type,
568                    impl_info.target_type
569                ),
570            );
571            dot.push_str(
572                &format!(
573                    "    \"{}\" -> \"{}\" [label=\"implements\"];\n", impl_info
574                    .target_type, impl_info.trait_name
575                ),
576            );
577        }
578        for trait_def in traits {
579            for supertrait in &trait_def.supertraits {
580                dot.push_str(
581                    &format!(
582                        "    \"{}\" -> \"{}\" [label=\"extends\", style=dashed];\n",
583                        trait_def.name, supertrait
584                    ),
585                );
586            }
587        }
588        dot.push_str("}\n");
589        Ok(dot)
590    }
591    fn suggest_trait_implementations(
592        &self,
593        traits: &[TraitDefinition],
594        implementations: &[TraitImplementation],
595    ) -> Vec<TraitSuggestion> {
596        let mut suggestions = Vec::new();
597        let common_types = vec![
598            "String", "i32", "i64", "bool", "Vec<T>", "HashMap<K, V>", "Option<T>",
599            "Result<T, E>"
600        ];
601        for trait_def in traits {
602            let implementation_count = implementations
603                .iter()
604                .filter(|impl_info| impl_info.trait_name == trait_def.name)
605                .count();
606            if implementation_count > 5 {
607                continue;
608            }
609            for common_type in &common_types {
610                let already_implemented = implementations
611                    .iter()
612                    .any(|impl_info| {
613                        impl_info.trait_name == trait_def.name
614                            && impl_info.target_type == *common_type
615                    });
616                if !already_implemented {
617                    let confidence = if common_type.contains("String")
618                        && trait_def.name.contains("Display")
619                    {
620                        0.9
621                    } else if common_type.contains("Vec")
622                        && trait_def.name.contains("IntoIterator")
623                    {
624                        0.8
625                    } else {
626                        0.5
627                    };
628                    suggestions
629                        .push(TraitSuggestion {
630                            trait_name: trait_def.name.clone(),
631                            target_type: common_type.to_string(),
632                            reason: format!(
633                                "{} would benefit from {} implementation", common_type,
634                                trait_def.name
635                            ),
636                            confidence,
637                        });
638                }
639            }
640        }
641        suggestions
642            .sort_by(|a, b| {
643                b.confidence
644                    .partial_cmp(&a.confidence)
645                    .unwrap_or(std::cmp::Ordering::Equal)
646            });
647        suggestions
648    }
649    fn generate_implementations_report(
650        &self,
651        _traits: &[TraitDefinition],
652        _implementations: &[TraitImplementation],
653    ) -> Result<String> {
654        Err(
655            ToolError::ExecutionFailed(
656                "Implementation report feature not yet implemented".to_string(),
657            ),
658        )
659    }
660    fn generate_missing_report(&self, _missing: &[String]) -> Result<String> {
661        Err(
662            ToolError::ExecutionFailed(
663                "Missing implementations report feature not yet implemented".to_string(),
664            ),
665        )
666    }
667    fn generate_suggestions_report(
668        &self,
669        _suggestions: &[TraitSuggestion],
670    ) -> Result<String> {
671        Err(
672            ToolError::ExecutionFailed(
673                "Suggestions report feature not yet implemented".to_string(),
674            ),
675        )
676    }
677}
678impl Tool for TraitExplorerTool {
679    fn name(&self) -> &'static str {
680        "trait-explorer"
681    }
682    fn description(&self) -> &'static str {
683        "Explore and analyze trait implementations across the workspace"
684    }
685    fn command(&self) -> Command {
686        Command::new(self.name())
687            .about(self.description())
688            .long_about(
689                "Discover all trait implementations in your codebase, analyze usage patterns, find missing implementations, and generate comprehensive trait documentation.",
690            )
691            .args(
692                &[
693                    Arg::new("input")
694                        .long("input")
695                        .short('i')
696                        .help("Input directory to analyze")
697                        .default_value("src/"),
698                    Arg::new("trait")
699                        .long("trait")
700                        .short('t')
701                        .help("Specific trait to explore"),
702                    Arg::new("implementations")
703                        .long("implementations")
704                        .help("Show all implementations of specified trait")
705                        .action(clap::ArgAction::SetTrue),
706                    Arg::new("missing")
707                        .long("missing")
708                        .help("Find missing trait implementations")
709                        .action(clap::ArgAction::SetTrue),
710                    Arg::new("usage")
711                        .long("usage")
712                        .help("Analyze trait usage patterns")
713                        .action(clap::ArgAction::SetTrue),
714                    Arg::new("visualize")
715                        .long("visualize")
716                        .short('v')
717                        .help("Generate trait relationship visualization")
718                        .action(clap::ArgAction::SetTrue),
719                    Arg::new("format")
720                        .long("format")
721                        .help("Output format: markdown, json, mermaid, dot")
722                        .default_value("markdown"),
723                    Arg::new("output")
724                        .long("output")
725                        .short('o')
726                        .help("Output file for analysis")
727                        .default_value("trait-analysis.md"),
728                    Arg::new("suggest")
729                        .long("suggest")
730                        .help("Suggest additional trait implementations")
731                        .action(clap::ArgAction::SetTrue),
732                    Arg::new("workspace")
733                        .long("workspace")
734                        .help("Analyze all crates in workspace")
735                        .action(clap::ArgAction::SetTrue),
736                ],
737            )
738            .args(&common_options())
739    }
740    fn execute(&self, matches: &ArgMatches) -> Result<()> {
741        let input = matches.get_one::<String>("input").unwrap();
742        let specific_trait = matches.get_one::<String>("trait");
743        let implementations_only = matches.get_flag("implementations");
744        let missing_only = matches.get_flag("missing");
745        let usage_analysis = matches.get_flag("usage");
746        let visualize = matches.get_flag("visualize");
747        let format = matches.get_one::<String>("format").unwrap();
748        let output = matches.get_one::<String>("output").unwrap();
749        let suggest = matches.get_flag("suggest");
750        let workspace = matches.get_flag("workspace");
751        let dry_run = matches.get_flag("dry-run");
752        let verbose = matches.get_flag("verbose");
753        let output_format = parse_output_format(matches);
754        println!(
755            "šŸ” {} - {}", "CargoMate TraitExplorer".bold().blue(), self.description()
756            .cyan()
757        );
758        if !Path::new(input).exists() {
759            return Err(
760                ToolError::InvalidArguments(format!("Input path not found: {}", input)),
761            );
762        }
763        if verbose {
764            println!("   šŸ“Š Analyzing trait ecosystem in {}", input);
765        }
766        let trait_definitions = self.discover_trait_definitions(input)?;
767        if verbose {
768            println!("   šŸ“‹ Found {} trait definitions", trait_definitions.len());
769        }
770        let trait_implementations = self.discover_trait_implementations(input)?;
771        if verbose {
772            println!(
773                "   šŸ“‹ Found {} trait implementations", trait_implementations.len()
774            );
775        }
776        let (filtered_definitions, filtered_implementations) = if let Some(trait_name) = specific_trait {
777            let defs: Vec<TraitDefinition> = trait_definitions
778                .into_iter()
779                .filter(|t| t.name == *trait_name)
780                .collect();
781            let impls: Vec<TraitImplementation> = trait_implementations
782                .into_iter()
783                .filter(|i| i.trait_name == *trait_name)
784                .collect();
785            (defs, impls)
786        } else {
787            (trait_definitions, trait_implementations)
788        };
789        if filtered_definitions.is_empty() {
790            println!("{}", "No traits found matching criteria.".yellow());
791            return Ok(());
792        }
793        let usage_patterns = self.analyze_trait_usage(&filtered_implementations)?;
794        let missing_implementations = self
795            .find_missing_implementations(
796                &filtered_definitions,
797                &filtered_implementations,
798            );
799        let suggestions = if suggest {
800            self.suggest_trait_implementations(
801                &filtered_definitions,
802                &filtered_implementations,
803            )
804        } else {
805            Vec::new()
806        };
807        let mut output_content = String::new();
808        if implementations_only {
809            output_content = self
810                .generate_implementations_report(
811                    &filtered_definitions,
812                    &filtered_implementations,
813                )?;
814        } else if missing_only {
815            output_content = self.generate_missing_report(&missing_implementations)?;
816        } else if visualize {
817            output_content = self
818                .generate_trait_visualization(
819                    &filtered_definitions,
820                    &filtered_implementations,
821                    format,
822                )?;
823        } else if suggest {
824            output_content = self.generate_suggestions_report(&suggestions)?;
825        } else {
826            output_content = self
827                .generate_trait_documentation(
828                    &filtered_definitions,
829                    &filtered_implementations,
830                )?;
831        }
832        match output_format {
833            OutputFormat::Human => {
834                println!("  āœ… Generated trait analysis");
835                println!("     → {}", output.cyan());
836                if implementations_only {
837                    println!(
838                        "  šŸ“‹ Showing implementations for {} traits",
839                        filtered_definitions.len()
840                    );
841                } else if missing_only {
842                    println!(
843                        "  āš ļø  Found {} potential missing implementations",
844                        missing_implementations.len()
845                    );
846                } else if visualize {
847                    println!("  šŸ“Š Generated {} visualization", format);
848                } else if suggest {
849                    println!(
850                        "  šŸ’” Generated {} implementation suggestions", suggestions
851                        .len()
852                    );
853                }
854                if dry_run {
855                    println!("   šŸ“‹ {}", "Analysis preview:".bold());
856                    println!("   {}", "─".repeat(50));
857                    for line in output_content.lines().take(15) {
858                        println!("   {}", line);
859                    }
860                    if output_content.lines().count() > 15 {
861                        println!("   ... (truncated)");
862                    }
863                } else {
864                    if let Some(parent) = Path::new(output).parent() {
865                        fs::create_dir_all(parent)
866                            .map_err(|e| ToolError::ExecutionFailed(
867                                format!("Failed to create output directory: {}", e),
868                            ))?;
869                    }
870                    fs::write(output, &output_content)
871                        .map_err(|e| ToolError::ExecutionFailed(
872                            format!("Failed to write {}: {}", output, e),
873                        ))?;
874                    println!("  šŸ’¾ Analysis written successfully");
875                }
876            }
877            OutputFormat::Json => {
878                let result = serde_json::json!(
879                    { "traits_analyzed" : filtered_definitions.len(),
880                    "implementations_found" : filtered_implementations.len(),
881                    "missing_implementations" : missing_implementations.len(),
882                    "suggestions_count" : suggestions.len(), "analysis_content" :
883                    output_content }
884                );
885                println!("{}", serde_json::to_string_pretty(& result).unwrap());
886            }
887            OutputFormat::Table => {
888                println!(
889                    "{:<25} {:<15} {:<12} {:<10} {:<12}", "Analysis Type", "Traits",
890                    "Impls", "Missing", "Suggestions"
891                );
892                println!("{}", "─".repeat(80));
893                println!(
894                    "{:<25} {:<15} {:<12} {:<10} {:<12}", if implementations_only {
895                    "Implementations" } else if missing_only { "Missing" } else if
896                    visualize { "Visualization" } else if suggest { "Suggestions" } else
897                    { "Full Analysis" }, filtered_definitions.len(),
898                    filtered_implementations.len(), missing_implementations.len(),
899                    suggestions.len()
900                );
901            }
902        }
903        println!("\nšŸŽ‰ Trait exploration completed!");
904        Ok(())
905    }
906}
907impl Default for TraitExplorerTool {
908    fn default() -> Self {
909        Self::new()
910    }
911}