preserves/implementations/rust/src/value/magic.rs

53 lines
1.5 KiB
Rust

use super::value::{
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<E>(self, v: u64) -> Result<Self::Value, E> where E: serde::de::Error {
let b = unsafe { Box::from_raw(v as *mut IOValue) };
Ok(*b)
}
}
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) ->
Result<S::Ok, S::Error>
{
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<IOValue, D::Error>
{
deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor)
}
//---------------------------------------------------------------------------
pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> Option<IOValue> {
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<F>(name: &'static str, f: F) -> Option<u64>
where F: FnOnce() -> IOValue
{
if name == MAGIC {
let b: Box<IOValue> = Box::new(f());
Some(Box::into_raw(b) as u64)
} else {
None
}
}