workspacer_syntax/
generate_struct_signature.rs

1// ---------------- [ File: workspacer-syntax/src/generate_struct_signature.rs ]
2crate::ix!();
3
4#[derive(Debug, Clone)]
5pub struct StructSignatureGenerator(ast::Struct);
6
7impl GenerateSignature for ast::Struct {
8    fn generate_signature_with_opts(&self, opts: &SignatureOptions) -> String {
9        trace!("Generating signature for ast::Struct with opts: {:?}", opts);
10
11        let doc_text = if *opts.include_docs() {
12            extract_docs(&self.syntax())
13                .map(|d| format!("{}\n", d))
14                .unwrap_or_default()
15        } else {
16            "".to_string()
17        };
18
19        let vis_str = self
20            .visibility()
21            .map(|v| format!("{} ", v.syntax().text()))
22            .unwrap_or_default();
23
24        let name_str = self
25            .name()
26            .map(|n| n.to_string())
27            .unwrap_or_else(|| "<unknown_struct>".to_string());
28
29        let generic_params_raw = self
30            .generic_param_list()
31            .map(|g| g.syntax().text().to_string())
32            .unwrap_or_default();
33
34        let where_clause_raw = self
35            .where_clause()
36            .map(|wc| wc.syntax().text().to_string())
37            .unwrap_or_default();
38        let where_clause = if where_clause_raw.is_empty() {
39            "".to_string()
40        } else {
41            format!(" {}", where_clause_raw)
42        };
43
44        // If fully_expand = true, let's gather actual fields:
45        // If false, placeholders.
46        let fields_text = if *opts.fully_expand() {
47            if let Some(fl) = self.field_list() {
48                match fl {
49                    ast::FieldList::RecordFieldList(rfl) => {
50                        let all_fields: Vec<String> = rfl
51                            .fields()
52                            .map(|field| {
53                                let fname = field
54                                    .name()
55                                    .map(|n| n.text().to_string())
56                                    .unwrap_or_default();
57                                let fty = field
58                                    .ty()
59                                    .map(|t| t.syntax().text().to_string())
60                                    .unwrap_or_default();
61                                format!("    {}: {},", fname, fty)
62                            })
63                            .collect();
64                        format!("{{\n{}\n}}", all_fields.join("\n"))
65                    }
66                    ast::FieldList::TupleFieldList(tfl) => {
67                        let all_fields: Vec<String> = tfl
68                            .fields()
69                            .map(|field| {
70                                let vis = field
71                                    .visibility()
72                                    .map(|v| format!("{} ", v.syntax().text()))
73                                    .unwrap_or_default();
74                                let fty = field
75                                    .ty()
76                                    .map(|t| t.syntax().text().to_string())
77                                    .unwrap_or_default();
78                                format!("    {}{},", vis, fty)
79                            })
80                            .collect();
81                        format!("(\n{}\n);", all_fields.join("\n"))
82                    }
83                }
84            } else {
85                // no fields => e.g. `struct Foo;`
86                ";".to_string()
87            }
88        } else {
89            // minimal or placeholder approach
90            "{ /* fields omitted */ }".to_string()
91        };
92
93        let core = format!(
94            "{vis_str}struct {name_str}{generic_params_raw}{where_clause} {fields_text}"
95        );
96
97        let final_sig = format!("{doc_text}{core}");
98        post_process_spacing(&final_sig)
99    }
100}