gather_all_code_from_crates/
parse_struct_item.rs

1crate::ix!();
2
3/// Parses a struct item from the AST node.
4pub fn parse_struct_item(strct: ast::Struct, remove_doc_comments: bool) -> ItemInfo {
5    let (_attributes, _is_test) = extract_attributes(strct.attrs());
6    let is_public = strct.visibility().map_or(false, |v| v.syntax().text().to_string().contains("pub"));
7    let name = strct.name().map(|n| n.text().to_string()).unwrap_or_default();
8
9    let original_text = strct.syntax().text().to_string();
10    let filtered = filter_doc_comments(&original_text, remove_doc_comments);
11
12    ItemInfo::Struct {
13        name,
14        attributes: vec![],
15        is_public,
16        signature: filtered.trim_end().to_string(),
17    }
18}
19
20#[cfg(test)]
21mod parse_struct_item_tests {
22    use super::*;
23
24    #[test]
25    fn test_parse_struct_item() {
26        let code = r#"
27#[derive(Debug)]
28pub struct MyStruct {
29    #[serde(default)]
30    field: i32,
31}
32"#;
33        let syntax = parse_source(code);
34        let strct = syntax.descendants().find_map(ast::Struct::cast).unwrap();
35        let item = parse_struct_item(strct, false);
36        if let ItemInfo::Struct { name, attributes, is_public, signature } = item {
37            assert_eq!(name, "MyStruct");
38            assert!(is_public);
39            assert!(attributes.iter().any(|a| a.contains("#[derive(Debug)]")));
40            assert!(signature.contains("pub struct MyStruct {"));
41            assert!(signature.contains("#[serde(default)]"));
42            assert!(signature.contains("field: i32,"));
43        } else {
44            panic!("Expected a struct item");
45        }
46    }
47
48    #[test]
49    fn test_parse_struct_item_basic() {
50        let code = r#"
51#[derive(Debug)]
52pub struct MyStruct {
53    #[serde(default)]
54    field: i32,
55}
56"#;
57        let syntax = parse_source(code);
58        let strct = syntax.descendants().find_map(ast::Struct::cast).unwrap();
59        let item = parse_struct_item(strct, false);
60        if let ItemInfo::Struct { name, attributes, is_public, signature } = item {
61            assert_eq!(name, "MyStruct");
62            assert!(is_public);
63            assert!(attributes.iter().any(|a| a.contains("#[derive(Debug)]")));
64            assert!(signature.contains("pub struct MyStruct {"));
65            assert!(signature.contains("#[serde(default)]"));
66            assert!(signature.contains("field: i32,"));
67        } else {
68            panic!("Expected a struct item");
69        }
70    }
71
72    #[test]
73    fn test_parse_struct_item_private() {
74        let code = r#"
75struct PrivateStruct;
76"#;
77        let syntax = parse_source(code);
78        let strct = syntax.descendants().find_map(ast::Struct::cast).unwrap();
79        let item = parse_struct_item(strct, false);
80        if let ItemInfo::Struct { name, is_public, signature, .. } = item {
81            assert_eq!(name, "PrivateStruct");
82            assert!(!is_public);
83            assert!(signature.contains("struct PrivateStruct;"));
84        } else {
85            panic!("Expected a struct item");
86        }
87    }
88
89    #[test]
90    fn test_parse_struct_item_remove_doc_comments() {
91        let code = r#"
92/// A documented struct
93struct DocStruct {}
94"#;
95        let syntax = parse_source(code);
96        let strct = syntax.descendants().find_map(ast::Struct::cast).unwrap();
97
98        let item = parse_struct_item(strct.clone(), true);
99        if let ItemInfo::Struct { signature, .. } = item {
100            assert!(!signature.contains("/// A documented struct"));
101        }
102
103        let item = parse_struct_item(strct.clone(), false);
104        if let ItemInfo::Struct { signature, .. } = item {
105            assert!(signature.contains("/// A documented struct"));
106        }
107    }
108}
109
110