workspacer_syntax/
generate_enum_signature.rs

1// ---------------- [ File: workspacer-syntax/src/generate_enum_signature.rs ]
2crate::ix!();
3
4#[derive(Debug, Clone)]
5pub struct EnumSignatureGenerator(ast::Enum);
6
7impl GenerateSignature for ast::Enum {
8    fn generate_signature_with_opts(&self, opts: &SignatureOptions) -> String {
9        trace!("Generating signature for ast::Enum 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 = self
25            .name()
26            .map(|n| n.text().to_string())
27            .unwrap_or_else(|| "<unknown_enum>".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, we gather actual variants:
45        let variants_text = if *opts.fully_expand() {
46            if let Some(variant_list) = self.variant_list() {
47                let items: Vec<String> = variant_list
48                    .variants()
49                    .map(|v| {
50                        let vname = v.name().map(|x| x.text().to_string()).unwrap_or_default();
51                        // If it has a field list, we expand them, else just the variant name
52                        if let Some(fl) = v.field_list() {
53                            match fl {
54                                ast::FieldList::RecordFieldList(rfl) => {
55                                    let fields: Vec<String> = rfl.fields().map(|f| {
56                                        let fname = f
57                                            .name()
58                                            .map(|n| n.text().to_string())
59                                            .unwrap_or_default();
60                                        let fty = f
61                                            .ty()
62                                            .map(|t| t.syntax().text().to_string())
63                                            .unwrap_or_default();
64                                        format!("{fname}: {fty}")
65                                    }).collect();
66                                    format!("{vname} {{ {} }}", fields.join(", "))
67                                }
68                                ast::FieldList::TupleFieldList(tfl) => {
69                                    let fields: Vec<String> = tfl.fields().map(|f| {
70                                        let fty = f.ty().map(|t| t.syntax().text().to_string()).unwrap_or_default();
71                                        fty
72                                    }).collect();
73                                    format!("{vname}({})", fields.join(", "))
74                                }
75                            }
76                        } else {
77                            // no fields
78                            vname
79                        }
80                    })
81                    .collect();
82                format!("{{\n    {},\n}}", items.join(",\n    "))
83            } else {
84                ";".to_string()
85            }
86        } else {
87            "{ /* variants omitted */ }".to_string()
88        };
89
90        let core = format!(
91            "{vis_str}enum {name}{generic_params_raw}{where_clause} {variants_text}"
92        );
93
94        let final_sig = format!("{doc_text}{core}");
95        post_process_spacing(&final_sig)
96    }
97}