use super::{ NullDomain, value::{ ArcValue, NestedValue, Domain, }, }; pub static MAGIC: &str = "$____Preserves_Serde_Magic"; pub type IOValue = ArcValue; 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) } } pub fn output_value(serializer: S, v: IOValue) -> Result { serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64)) } pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result { deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor) } pub fn input_value_via<'de, D: serde::Deserializer<'de>, N: NestedValue, Dom: Domain>(deserializer: D) -> Result { Ok(input_value(deserializer)?.copy_via(&|_| unreachable!())) } //--------------------------------------------------------------------------- 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 } } pub fn transmit_input_value(name: &'static str, f: F) -> Option where F: FnOnce() -> IOValue { if name == MAGIC { let b: Box = Box::new(f()); Some(Box::into_raw(b) as u64) } else { None } }