2023-10-26 22:46:27 +00:00
|
|
|
#![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 <https://gitlab.com/preserves/preserves/-/issues/42>.
|
|
|
|
|
2021-03-12 10:04:23 +00:00
|
|
|
use super::repr::IOValue;
|
2020-05-26 07:08:17 +00:00
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
2023-07-21 16:15:30 +00:00
|
|
|
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
2020-05-26 07:08:17 +00:00
|
|
|
let b = unsafe { Box::from_raw(v as *mut IOValue) };
|
|
|
|
Ok(*b)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-30 11:07:01 +00:00
|
|
|
#[inline(always)]
|
2023-07-21 16:15:30 +00:00
|
|
|
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) -> Result<S::Ok, S::Error> {
|
2020-05-26 07:08:17 +00:00
|
|
|
serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64))
|
|
|
|
}
|
|
|
|
|
2021-09-30 11:07:01 +00:00
|
|
|
#[inline(always)]
|
2023-07-21 16:15:30 +00:00
|
|
|
pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<IOValue, D::Error> {
|
2020-05-26 07:08:17 +00:00
|
|
|
deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor)
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2020-05-27 07:04:55 +00:00
|
|
|
#[inline]
|
2020-05-26 07:08:17 +00:00
|
|
|
pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> Option<IOValue> {
|
|
|
|
if name == MAGIC {
|
2023-07-21 16:15:30 +00:00
|
|
|
let b =
|
|
|
|
unsafe { Box::from_raw(*((magic_value as *const T) as *const u64) as *mut IOValue) };
|
2020-05-26 07:08:17 +00:00
|
|
|
let v: IOValue = *b;
|
|
|
|
Some(v)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 07:04:55 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn transmit_input_value<F>(name: &'static str, f: F) -> Result<Option<u64>, crate::error::Error>
|
2023-07-21 16:15:30 +00:00
|
|
|
where
|
|
|
|
F: FnOnce() -> Result<IOValue, crate::error::Error>,
|
2020-05-26 07:08:17 +00:00
|
|
|
{
|
|
|
|
if name == MAGIC {
|
2020-05-27 07:04:55 +00:00
|
|
|
let b: Box<IOValue> = Box::new(f()?);
|
|
|
|
Ok(Some(Box::into_raw(b) as u64))
|
2020-05-26 07:08:17 +00:00
|
|
|
} else {
|
2020-05-27 07:04:55 +00:00
|
|
|
Ok(None)
|
2020-05-26 07:08:17 +00:00
|
|
|
}
|
|
|
|
}
|