introspect_core/
member.rs

1use proc_macro2::TokenStream;
2use quote::ToTokens;
3
4use crate::r#enum::Variant;
5use crate::r#struct::Field;
6
7/// A member of a Rust construct.
8#[derive(Debug)]
9pub enum Member {
10    /// A struct field.
11    Field(Field),
12
13    /// An enum variant.
14    Variant(Variant),
15}
16
17impl std::fmt::Display for Member {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            Member::Field(field) => write!(f, "::introspect::Member::Field({})", field),
21            Member::Variant(variant) => write!(f, "::introspect::Member::Variant({})", variant),
22        }
23    }
24}
25
26impl ToTokens for Member {
27    fn to_tokens(&self, tokens: &mut TokenStream) {
28        // SAFETY: this unwrap should never fail as we exhaustively test converting a
29        // [`Member`] to a string that eventually parses to a token stream.
30        tokens.extend(self.to_string().parse::<TokenStream>().unwrap())
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn an_enum_variant_converts_to_string_correctly() {
40        let member = Member::Variant(Variant::new("Name".into(), Some("Documentation.".into())));
41
42        assert_eq!(member.to_string(), "::introspect::Member::Variant(::introspect::r#enum::Variant::new(r#\"Name\"#.into(), Some(r#\"Documentation.\"#.into())))");
43    }
44
45    #[test]
46    fn a_struct_field_converts_to_string_correctly() {
47        let member = Member::Field(Field::new(
48            Some("Name".into()),
49            Some("Documentation.".into()),
50        ));
51
52        assert_eq!(member.to_string(), "::introspect::Member::Field(::introspect::r#struct::Field::new(Some(r#\"Name\"#.into()), Some(r#\"Documentation.\"#.into())))");
53    }
54}