#![doc(hidden)] //! A horrifying hack to Serde-serialize [IOValue] instances to Preserves *as themselves*. //! //! Frankly I think this portion of the codebase might not survive for long. I can't think of a //! better way of achieving this, but the drawbacks of having this functionality are *severe*. //! //! See . use super::repr::IOValue; pub static MAGIC: &str = "$____Preserves_Serde_Magic"; struct IOValueVisitor; impl<'de> serde::de::Visitor<'de> for IOValueVisitor { type Value = IOValue; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { write!(formatter, "a magic encoding of an embedded Preserves Value") } fn visit_u64(self, v: u64) -> Result where E: serde::de::Error, { let b = unsafe { Box::from_raw(v as *mut IOValue) }; Ok(*b) } } #[inline(always)] pub fn output_value(serializer: S, v: IOValue) -> Result { serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64)) } #[inline(always)] pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result { deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor) } //--------------------------------------------------------------------------- #[inline] pub fn receive_output_value(name: &'static str, magic_value: &T) -> Option { if name == MAGIC { let b = unsafe { Box::from_raw(*((magic_value as *const T) as *const u64) as *mut IOValue) }; let v: IOValue = *b; Some(v) } else { None } } #[inline] pub fn transmit_input_value(name: &'static str, f: F) -> Result, crate::error::Error> where F: FnOnce() -> Result, { if name == MAGIC { let b: Box = Box::new(f()?); Ok(Some(Box::into_raw(b) as u64)) } else { Ok(None) } }