facet_macros_impl/
lib.rs

1#![warn(missing_docs)]
2#![allow(uncommon_codepoints)]
3#![doc = include_str!("../README.md")]
4
5// ============================================================================
6// RE-EXPORTS FROM FACET-MACRO-TYPES (grammar) AND FACET-MACRO-PARSE (parsed types)
7// ============================================================================
8
9// Re-export everything from facet-macro-types (includes unsynn, grammar, RenameRule)
10pub use facet_macro_types::*;
11
12// Re-export everything from facet-macro-parse (includes parsed types like PStruct, PEnum, etc.)
13pub use facet_macro_parse::*;
14
15// ============================================================================
16// FUNCTION PARSING (optional feature)
17// ============================================================================
18
19/// Parse function signature shape
20#[cfg(feature = "function")]
21pub mod function;
22
23// ============================================================================
24// CODE EMISSION
25// ============================================================================
26
27mod process_enum;
28mod process_struct;
29
30mod derive;
31pub use derive::*;
32
33mod plugin;
34pub use plugin::*;
35
36mod extension;
37pub use extension::*;
38
39mod on_error;
40pub use on_error::*;
41
42/// Attribute grammar infrastructure for extension crates
43pub mod attr_grammar;
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48    use quote::quote;
49
50    #[test]
51    fn test_struct_with_field_doc_comments() {
52        let input = quote! {
53            #[derive(Facet)]
54            pub struct User {
55                #[doc = " The user's unique identifier"]
56                pub id: u64,
57            }
58        };
59
60        let mut it = input.to_token_iter();
61        let parsed = it.parse::<Struct>().expect("Failed to parse struct");
62
63        // Check that we parsed the struct correctly
64        assert_eq!(parsed.name.to_string(), "User");
65
66        // Extract fields from the struct
67        if let StructKind::Struct { fields, .. } = &parsed.kind {
68            assert_eq!(fields.content.len(), 1);
69
70            // Check first field (id)
71            let id_field = &fields.content[0].value;
72            assert_eq!(id_field.name.to_string(), "id");
73
74            // Extract doc comments from id field
75            let mut doc_found = false;
76            for attr in &id_field.attributes {
77                match &attr.body.content {
78                    AttributeInner::Doc(doc_inner) => {
79                        // This should work with LiteralString
80                        assert_eq!(doc_inner.value, " The user's unique identifier");
81                        doc_found = true;
82                    }
83                    _ => {
84                        // Skip non-doc attributes
85                    }
86                }
87            }
88            assert!(doc_found, "Should have found a doc comment");
89        } else {
90            panic!("Expected a regular struct with named fields");
91        }
92    }
93}