Less safe but drastically more efficient raw-value (de)serialization

This commit is contained in:
Tony Garnock-Jones 2020-05-24 13:47:42 +02:00
parent bddb4331aa
commit 67bf47a5c9
4 changed files with 46 additions and 59 deletions

View File

@ -4,7 +4,7 @@ use super::value::{
Value, NestedValue, PlainValue,
Domain, NullDomain,
DecodePlaceholderMap, EncodePlaceholderMap, invert_map,
Decoder, Encoder, to_value,
Encoder,
};
type Result<T> = std::result::Result<T, Error>;
@ -185,11 +185,15 @@ impl<'a, W: Writer, N: NestedValue<D>, D: Domain> serde::Serializer for &'a mut
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
Result<()> where T: Serialize
{
if name == crate::value::value::MAGIC {
let v0: N = to_value(value)?;
let mut buf: &[u8] = v0.value().as_bytestring().ok_or_else(magic_error)?;
let v1: N = Decoder::new(&mut buf, None).next().or_else(|_| Err(magic_error()))?;
Encoder::new(&mut self.write, self.placeholders.as_ref()).write(&v1)?;
if name == crate::value::value::MAGIC_VALUE {
let b = unsafe { Box::from_raw(*((value as *const T) as *const u64) as *mut &Value<N, D>) };
let v: &Value<N, D> = *b;
Encoder::new(&mut self.write, self.placeholders.as_ref()).write_value(v)?;
Ok(())
} else if name == crate::value::value::MAGIC_NESTEDVALUE {
let b = unsafe { Box::from_raw(*((value as *const T) as *const u64) as *mut &N) };
let v: &N = *b;
Encoder::new(&mut self.write, self.placeholders.as_ref()).write(v)?;
Ok(())
} else {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?

View File

@ -201,11 +201,12 @@ impl<'de, 'a, N: NestedValue<D>, D: 'de + Domain> serde::de::Deserializer<'de>
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value, D> where V: Visitor<'de>
{
if name == crate::value::value::MAGIC {
let mut buf: Vec<u8> = Vec::new();
crate::value::Encoder::new(&mut buf, None).write(self.input)
.or_else(|_e| Err(Error::InternalMagicError))?;
visitor.visit_byte_buf(buf)
if name == crate::value::value::MAGIC_VALUE {
let v: Box<Value<N, D>> = Box::new(self.input.clone().value_owned());
visitor.visit_u64(Box::into_raw(v) as u64)
} else if name == crate::value::value::MAGIC_NESTEDVALUE {
let v: Box<N> = Box::new(self.input.clone());
visitor.visit_u64(Box::into_raw(v) as u64)
} else {
let fs = self.check(|v| v.as_simple_record(name, Some(1)),
ExpectedKind::SimpleRecord(name, Some(1)))?;

View File

@ -119,10 +119,14 @@ impl<N: NestedValue<D>, D: Domain> serde::Serializer for Serializer<N, D> {
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
Result<Self::Ok, D> where T: Serialize
{
if name == crate::value::value::MAGIC {
let v: crate::value::PlainValue<D> = to_value(value)?;
let mut buf: &[u8] = v.value().as_bytestring().ok_or(Error::InternalMagicError)?;
crate::value::Decoder::new(&mut buf, None).next().or(Err(Error::InternalMagicError))
if name == crate::value::value::MAGIC_VALUE {
let b = unsafe { Box::from_raw(*((value as *const T) as *const u64) as *mut &Value<N, D>) };
let v: &Value<N, D> = *b;
Ok(v.clone().wrap())
} else if name == crate::value::value::MAGIC_NESTEDVALUE {
let b = unsafe { Box::from_raw(*((value as *const T) as *const u64) as *mut &N) };
let v: &N = *b;
Ok(v.clone())
} else {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
Ok(Value::simple_record(name, vec![to_value(value)?]).wrap())

View File

@ -549,67 +549,45 @@ impl<N: NestedValue<D>, D: Domain> Index<&N> for Value<N, D> {
//---------------------------------------------------------------------------
// This part is a terrible hack
pub static MAGIC: &str = "$____Preserves_Value";
#[derive(serde::Serialize)]
#[serde(rename = "$____Preserves_Value")]
struct ValueWrapper(#[serde(with = "serde_bytes")] Vec<u8>);
struct ValueWrapperVisitor;
impl<'de> serde::de::Visitor<'de> for ValueWrapperVisitor {
type Value = ValueWrapper;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "an encoded value wrapper")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(ValueWrapper(Vec::from(v)))
}
}
impl<'de> serde::Deserialize<'de> for ValueWrapper {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_newtype_struct(MAGIC, ValueWrapperVisitor)
}
}
pub static MAGIC_VALUE: &str = "$____Preserves_Value";
pub static MAGIC_NESTEDVALUE: &str = "$____Preserves_NestedValue";
impl<N: NestedValue<D>, D: Domain> serde::Serialize for Value<N, D> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
let mut buf: Vec<u8> = Vec::new();
crate::value::Encoder::new(&mut buf, None).write_value(self)
.or_else(|_| Err(serde::ser::Error::custom("Internal error")))?;
ValueWrapper(buf).serialize(serializer)
serializer.serialize_newtype_struct(MAGIC_VALUE, &(Box::into_raw(Box::new(self)) as u64))
}
}
struct CastVisitor<T>(std::marker::PhantomData<T>);
impl<'de, T> serde::de::Visitor<'de> for CastVisitor<T> {
type Value = T;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a magic encoding of an embedded 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 T) };
Ok(*b)
}
}
impl<'de, N: NestedValue<Dom>, Dom: Domain> serde::Deserialize<'de> for Value<N, Dom> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
let ValueWrapper(buf) = ValueWrapper::deserialize(deserializer)?;
let v: N = crate::value::Decoder::new(&mut &buf[..], None).next()
.or_else(|_| Err(serde::de::Error::custom("Internal error")))?;
Ok(v.value_owned())
deserializer.deserialize_newtype_struct(
MAGIC_VALUE, CastVisitor::<Value<N, Dom>>(std::marker::PhantomData))
}
}
pub fn serialize_nested_value<S, N, D: Domain>(v: &N, serializer: S) ->
Result<S::Ok, S::Error> where S: serde::Serializer, N: NestedValue<D>
Result<S::Ok, S::Error> where S: serde::Serializer, N: NestedValue<D> + serde::Serialize
{
use serde::Serialize;
let mut buf: Vec<u8> = Vec::new();
crate::value::Encoder::new(&mut buf, None).write(v)
.or_else(|_| Err(serde::ser::Error::custom("Internal error")))?;
ValueWrapper(buf).serialize(serializer)
serializer.serialize_newtype_struct(MAGIC_NESTEDVALUE, &(Box::into_raw(Box::new(v)) as u64))
}
pub fn deserialize_nested_value<'de, D, N, Dom: Domain>(deserializer: D) ->
Result<N, D::Error> where D: serde::Deserializer<'de>, N: NestedValue<Dom>
Result<N, D::Error> where D: serde::Deserializer<'de>, N: NestedValue<Dom> + serde::Deserialize<'de>
{
use serde::Deserialize;
let ValueWrapper(buf) = ValueWrapper::deserialize(deserializer)?;
crate::value::Decoder::new(&mut &buf[..], None).next()
.or_else(|_| Err(serde::de::Error::custom("Internal error")))
deserializer.deserialize_newtype_struct(
MAGIC_NESTEDVALUE, CastVisitor::<N>(std::marker::PhantomData))
}
//---------------------------------------------------------------------------