serde_aux/
serde_introspection.rs
1use serde::de::{self, Deserialize, Deserializer, Visitor};
2
3pub fn serde_introspect<'de, T>() -> &'static [&'static str]
36where
37 T: Deserialize<'de>,
38{
39 struct StructFieldsDeserializer<'a> {
40 fields: &'a mut Option<&'static [&'static str]>,
41 }
42
43 impl<'de> Deserializer<'de> for StructFieldsDeserializer<'_> {
44 type Error = serde::de::value::Error;
45
46 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
47 where
48 V: Visitor<'de>,
49 {
50 Err(de::Error::custom("I'm just here for the fields"))
51 }
52
53 fn deserialize_struct<V>(
54 self,
55 _name: &'static str,
56 fields: &'static [&'static str],
57 _visitor: V,
58 ) -> Result<V::Value, Self::Error>
59 where
60 V: Visitor<'de>,
61 {
62 *self.fields = Some(fields); Err(de::Error::custom("I'm just here for the fields"))
64 }
65
66 serde::forward_to_deserialize_any! {
67 bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
68 byte_buf option unit unit_struct newtype_struct seq tuple
69 tuple_struct map enum identifier ignored_any
70 }
71 }
72
73 struct EnumVariantsDeserializer<'a> {
74 variants: &'a mut Option<&'static [&'static str]>,
75 }
76
77 impl<'de> Deserializer<'de> for EnumVariantsDeserializer<'_> {
78 type Error = serde::de::value::Error;
79
80 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
81 where
82 V: Visitor<'de>,
83 {
84 Err(de::Error::custom("I'm just here for the fields"))
85 }
86
87 fn deserialize_enum<V>(
88 self,
89 _name: &'static str,
90 variants: &'static [&'static str],
91 _visitor: V,
92 ) -> Result<V::Value, Self::Error>
93 where
94 V: Visitor<'de>,
95 {
96 *self.variants = Some(variants);
97 Err(de::Error::custom("I'm just here for the fields"))
98 }
99
100 serde::forward_to_deserialize_any! {
101 bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
102 byte_buf option unit unit_struct newtype_struct seq tuple
103 tuple_struct map struct identifier ignored_any
104 }
105 }
106
107 let mut serialized_names = None;
108 let _ = T::deserialize(EnumVariantsDeserializer {
109 variants: &mut serialized_names,
110 });
111 let _ = T::deserialize(StructFieldsDeserializer {
112 fields: &mut serialized_names,
113 });
114 serialized_names.unwrap_or_default()
115}
116
117pub fn get_default_serde_record<'de, T>() -> Result<T, serde::de::value::Error>
163where
164 T: Deserialize<'de>,
165{
166 let empty_data = std::iter::empty::<((), ())>();
167 let empty_deserializer =
168 serde::de::value::MapDeserializer::<_, serde::de::value::Error>::new(empty_data);
169 T::deserialize(empty_deserializer)
170}
171
172#[cfg(test)]
173mod tests {
174 #![allow(dead_code)]
175
176 use crate::prelude::{get_default_serde_record, serde_introspect};
177
178 #[test]
179 fn serde_introspect_given_struct_introspect_serialization_names() {
180 #[derive(serde::Deserialize, Debug)]
181 enum SomeEnum {
182 #[serde(rename = "a")]
183 EnumA,
184 #[serde(rename = "b")]
185 EnumB,
186 }
187 #[derive(serde::Deserialize, Debug)]
188 struct AnotherStruct {
189 #[serde(rename = "a3")]
190 aaa: Option<i64>,
191 #[serde(rename = "b3")]
192 bbb: i128,
193 #[serde(rename = "c3")]
194 ccc: u128,
195 #[serde(rename = "d3")]
196 ddd: SomeEnum,
197 }
198 let names = serde_introspect::<AnotherStruct>();
199 assert_eq!(names[0], "a3");
200 assert_eq!(names[1], "b3");
201 assert_eq!(names[2], "c3");
202 assert_eq!(names[3], "d3");
203 }
204
205 #[test]
206 fn serde_introspect_enum_struct_introspect_serialization_names() {
207 #[derive(serde::Deserialize, Debug)]
208 enum SomeEnum {
209 #[serde(rename = "a")]
210 EnumA,
211 #[serde(rename = "b")]
212 EnumB,
213 }
214
215 let names = serde_introspect::<SomeEnum>();
216 assert_eq!(names[0], "a");
217 assert_eq!(names[1], "b");
218 }
219
220 #[test]
221 fn get_default_serde_record_from_struct() {
222 #[derive(serde::Deserialize, PartialEq, Debug)]
223 struct Record {
224 #[serde(default = "default_string")]
225 label: String,
226 #[serde(default = "default_f64")]
227 value1: f64,
228 #[serde(default)]
229 value2: f64,
230 #[serde(skip)]
231 foo: bool,
232 }
233
234 fn default_string() -> String {
235 String::from("default")
236 }
237
238 fn default_f64() -> f64 {
239 1.0
240 }
241
242 let empty_record = get_default_serde_record::<Record>().unwrap();
243 assert_eq!(
244 empty_record,
245 Record {
246 label: String::from("default"),
247 value1: 1.0,
248 value2: 0.0,
249 foo: false
250 }
251 );
252 }
253}