sedes/de/
magical.rs

1use std::{error::Error, mem::ManuallyDrop, pin::Pin};
2
3pub struct MagicalDeserializer<'r> {
4    /// Don't R/W from this address until dropping the "dependant",
5    /// which uniquely borrows the addressed value.
6    boxed_dependency: *mut (dyn crate::util::Something + 'r),
7    /// Should be dropped first. Should not be taken out of the field.
8    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            // We trust the called function to not take the value out of the field.
43            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}