1use std::{error::Error, mem::ManuallyDrop, pin::Pin};
2
3pub struct MagicalDeserializer<'r> {
4 boxed_dependency: *mut (dyn crate::util::Something + 'r),
7 erased_dependant: ManuallyDrop<Pin<Box<dyn erased_serde::Deserializer<'r> + 'r>>>,
9}
10
11impl<'r> MagicalDeserializer<'r> {
12 pub fn from_direct_impl<T>(typed_deserializer: T) -> Self
13 where
14 T: serde::Deserializer<'r> + 'r,
15 {
16 Self {
17 boxed_dependency: Box::leak(Box::new(())),
18 erased_dependant: ManuallyDrop::new(Box::pin(<dyn erased_serde::Deserializer>::erase(
19 typed_deserializer,
20 ))),
21 }
22 }
23
24 pub fn new<T>(typed_deserializer: T) -> Self
25 where
26 T: 'r,
27 &'r mut T: serde::Deserializer<'r>,
28 {
29 let boxed_dependency: *mut T = Box::leak(Box::new(typed_deserializer));
30 Self {
31 boxed_dependency,
32 erased_dependant: ManuallyDrop::new(Box::pin(<dyn erased_serde::Deserializer>::erase(
33 unsafe { &mut *boxed_dependency },
34 ))),
35 }
36 }
37
38 pub fn deserialize<'o, O: serde::de::DeserializeOwned>(
39 &mut self,
40 ) -> Result<O, impl Error + 'static> {
41 erased_serde::deserialize(unsafe {
42 self.erased_dependant.as_mut().get_unchecked_mut()
44 })
45 }
46}
47impl<'r> Drop for MagicalDeserializer<'r> {
48 fn drop(&mut self) {
49 unsafe {
50 drop(ManuallyDrop::take(&mut self.erased_dependant));
51 drop(Box::from_raw(self.boxed_dependency));
52 }
53 }
54}
55
56#[cfg(test)]
57mod test {
58 cfg_if::cfg_if! {
59 if #[cfg(feature="json")] {
60 use std::sync::LazyLock;
61 static JSON_OBJ: LazyLock<&str> = LazyLock::new(|| "{\"zero\":0,\"k\":42}");
62 }
63 }
64
65 #[cfg(feature = "json")]
66 #[test]
67 fn deserializes_int_from_json() {
68 let json_data = b"3";
69 let mut source = &json_data[..];
70 let typed_deserializer = serde_json::Deserializer::from_reader(&mut source);
71 let mut magical_deserializer = crate::MagicalDeserializer::new(typed_deserializer);
72 let result: i32 = magical_deserializer.deserialize().unwrap();
73 assert_eq!(result, 3);
74 }
75
76 #[cfg(feature = "yaml")]
77 #[test]
78 fn deserializes_int_from_yaml() {
79 let yaml_data = b"2\n";
80 let mut source = &yaml_data[..];
81 let typed_deserializer = serde_yaml::Deserializer::from_reader(&mut source);
82 let mut magical_deserializer =
83 crate::MagicalDeserializer::from_direct_impl(typed_deserializer);
84 let result: i32 = magical_deserializer.deserialize().unwrap();
85 assert_eq!(result, 2);
86 }
87
88 #[cfg(feature = "json")]
89 #[test]
90 fn deserializes_static_obj_from_json() {
91 let mut source = JSON_OBJ.as_bytes();
92 let typed_deserializer = serde_json::Deserializer::from_reader(&mut source);
93 let mut magical_deserializer = crate::MagicalDeserializer::new(typed_deserializer);
94 let result: serde_json::Value = magical_deserializer.deserialize().unwrap();
95 let expected: serde_json::Value = serde_json::from_str(&JSON_OBJ).unwrap();
96 assert_eq!(result, expected);
97 }
98}