1use syn::Data;
17
18pub trait DataExt {
33 fn is_struct(&self) -> bool;
35 fn is_enum(&self) -> bool;
37 fn is_union(&self) -> bool;
39 fn as_struct(&self) -> Option<&syn::DataStruct>;
41 fn as_enum(&self) -> Option<&syn::DataEnum>;
43 fn as_union(&self) -> Option<&syn::DataUnion>;
45}
46
47impl DataExt for Data {
48 fn is_struct(&self) -> bool {
49 matches!(self, Self::Struct(_))
50 }
51
52 fn is_enum(&self) -> bool {
53 matches!(self, Self::Enum(_))
54 }
55
56 fn is_union(&self) -> bool {
57 matches!(self, Self::Union(_))
58 }
59
60 fn as_struct(&self) -> Option<&syn::DataStruct> {
61 match self {
62 Self::Struct(s) => Some(s),
63 _ => None,
64 }
65 }
66
67 fn as_enum(&self) -> Option<&syn::DataEnum> {
68 match self {
69 Self::Enum(e) => Some(e),
70 _ => None,
71 }
72 }
73
74 fn as_union(&self) -> Option<&syn::DataUnion> {
75 match self {
76 Self::Union(u) => Some(u),
77 _ => None,
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 fn data_from(input: &str) -> Data {
87 let di: syn::DeriveInput = syn::parse_str(input).unwrap();
88 di.data
89 }
90
91 mod predicates {
92 use super::*;
93
94 #[test]
95 fn struct_variant() {
96 let data = data_from("struct Foo { x: i32 }");
97 assert!(data.is_struct());
98 assert!(!data.is_enum());
99 assert!(!data.is_union());
100 }
101
102 #[test]
103 fn enum_variant() {
104 let data = data_from("enum Foo { A, B }");
105 assert!(!data.is_struct());
106 assert!(data.is_enum());
107 assert!(!data.is_union());
108 }
109
110 #[test]
111 fn union_variant() {
112 let data = data_from("union Foo { x: i32, y: u32 }");
113 assert!(!data.is_struct());
114 assert!(!data.is_enum());
115 assert!(data.is_union());
116 }
117 }
118
119 mod conversions {
120 use super::*;
121
122 #[test]
123 fn as_struct_some() {
124 let data = data_from("struct Foo { x: i32 }");
125 assert!(data.as_struct().is_some());
126 }
127
128 #[test]
129 fn as_struct_none() {
130 let data = data_from("enum Foo { A }");
131 assert!(data.as_struct().is_none());
132 }
133
134 #[test]
135 fn as_enum_some() {
136 let data = data_from("enum Foo { A, B }");
137 assert!(data.as_enum().is_some());
138 }
139
140 #[test]
141 fn as_enum_none() {
142 let data = data_from("struct Foo;");
143 assert!(data.as_enum().is_none());
144 }
145
146 #[test]
147 fn as_union_some() {
148 let data = data_from("union Foo { x: i32, y: u32 }");
149 assert!(data.as_union().is_some());
150 }
151
152 #[test]
153 fn as_union_none() {
154 let data = data_from("struct Foo;");
155 assert!(data.as_union().is_none());
156 }
157 }
158}