workspacer_syntax/
generate_trait_signature.rs

1// ---------------- [ File: workspacer-syntax/src/generate_trait_signature.rs ]
2crate::ix!();
3
4#[derive(Debug, Clone)]
5pub struct TraitSignatureGenerator(ast::Trait);
6
7impl GenerateSignature for ast::Trait {
8    fn generate_signature(&self) -> String {
9        // Just call the "with_opts" version using default SignatureOptions.
10        trace!("generate_signature called on ast::Trait (no custom opts)");
11        self.generate_signature_with_opts(&SignatureOptions::default())
12    }
13
14    fn generate_signature_with_opts(&self, opts: &SignatureOptions) -> String {
15        trace!("generate_signature_with_opts called on ast::Trait; fully_expand = {}", opts.fully_expand());
16
17        // 1) Gather trait visibility, name, generics:
18        let vis = if let Some(vis) = self.visibility() {
19            let txt = vis.syntax().text().to_string();
20            trace!("Trait visibility: {:?}", txt);
21            format!("{} ", txt)
22        } else {
23            "".to_string()
24        };
25
26        let name = self.name()
27            .map(|it| it.text().to_string())
28            .unwrap_or_else(|| "<anon_trait>".to_string());
29        trace!("Trait name: {:?}", name);
30
31        let generics = self.generic_param_list()
32            .map(|gp| gp.syntax().text().to_string())
33            .unwrap_or_default();
34        if !generics.is_empty() {
35            trace!("Trait generics: {:?}", generics);
36        }
37
38        /*
39        // 2) If we're *not* fully expanding, just produce a placeholder:
40        // we typically never want to do this
41        if !*opts.fully_expand() {
42            trace!("Not fully expanding trait items; returning short signature");
43            return format!("{}trait {}{} {{ /* trait items here */ }}", vis, name, generics);
44        }
45        */
46
47        // 3) If we *are* fully expanding, gather the trait's associated items:
48        let mut lines = Vec::new();
49        if let Some(item_list) = self.assoc_item_list() {
50            for assoc in item_list.assoc_items() {
51                // Methods:
52                if let Some(fn_ast) = ast::Fn::cast(assoc.syntax().clone()) {
53                    let mut opts = opts.clone();
54                    opts.set_add_semicolon(true);
55                    // We can rely on our existing `GenerateSignature` for `ast::Fn`,
56                    // or define a short signature ourselves. Here, we'll just call
57                    // fn_ast.generate_signature() for consistency:
58                    let method_sig = fn_ast.generate_signature_with_opts(&opts);
59                    lines.push(method_sig);
60
61                // Associated types:
62                } else if let Some(type_ast) = ast::TypeAlias::cast(assoc.syntax().clone()) {
63                    // For now, just push the raw text. You could parse out `type Foo;`
64                    // or `type Foo = Something;` more elegantly if desired.
65                    let raw_txt = type_ast.syntax().text().to_string();
66                    lines.push(raw_txt);
67
68                // Associated consts, etc.:
69                } else if let Some(const_ast) = ast::Const::cast(assoc.syntax().clone()) {
70                    let raw_txt = const_ast.syntax().text().to_string();
71                    lines.push(raw_txt);
72                }
73            }
74        }
75
76        // 4) Format each line with indentation inside the trait braces:
77        let mut items_str = String::new();
78        for line in lines {
79            for sub_line in line.lines() {
80                items_str.push_str("    ");
81                items_str.push_str(sub_line);
82                items_str.push('\n');
83            }
84        }
85
86        if items_str.trim().is_empty() {
87            trace!("No associated items found in trait; returning empty braces");
88            format!("{}trait {}{} {{}}", vis, name, generics)
89        } else {
90            trace!("Returning fully expanded trait signature with items");
91            format!("{}trait {}{} {{\n{}}}", vis, name, generics, items_str)
92        }
93    }
94}