378 lines
9.1 KiB
Rust
378 lines
9.1 KiB
Rust
//! Support for Serde serialization of Rust data types into Preserves *values* (not syntax).
|
|
|
|
use crate::value::{repr::Record, IOValue, Map, Value};
|
|
use serde::Serialize;
|
|
|
|
/// Empty/placeholder type for representing serialization errors: serialization to values
|
|
/// cannot fail.
|
|
#[derive(Debug)]
|
|
pub enum Error {}
|
|
impl serde::ser::Error for Error {
|
|
fn custom<T>(_: T) -> Self
|
|
where
|
|
T: std::fmt::Display,
|
|
{
|
|
unreachable!()
|
|
}
|
|
}
|
|
impl std::error::Error for Error {}
|
|
impl std::fmt::Display for Error {
|
|
fn fmt(&self, _fmt: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
|
|
unreachable!()
|
|
}
|
|
}
|
|
|
|
type Result<T> = std::result::Result<T, Error>;
|
|
|
|
/// Serde serializer for converting Rust data to in-memory Preserves values, which can then be
|
|
/// serialized using text or binary syntax, analyzed further, etc.
|
|
pub struct Serializer;
|
|
|
|
#[doc(hidden)]
|
|
pub struct SerializeDictionary {
|
|
next_key: Option<IOValue>,
|
|
items: Map<IOValue, IOValue>,
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
pub struct SerializeRecord {
|
|
r: Record<IOValue>,
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
pub struct SerializeSequence {
|
|
vec: Vec<IOValue>,
|
|
}
|
|
|
|
impl serde::Serializer for Serializer {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
type SerializeSeq = SerializeSequence;
|
|
type SerializeTuple = SerializeRecord;
|
|
type SerializeTupleStruct = SerializeRecord;
|
|
type SerializeTupleVariant = SerializeRecord;
|
|
type SerializeMap = SerializeDictionary;
|
|
type SerializeStruct = SerializeRecord;
|
|
type SerializeStructVariant = SerializeRecord;
|
|
|
|
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
|
|
Ok(Value::from(v as f64).wrap())
|
|
}
|
|
|
|
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
|
Ok(Value::simple_record1("UnicodeScalar", Value::from(v as u32).wrap()).wrap())
|
|
}
|
|
|
|
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
|
|
Ok(Value::from(v).wrap())
|
|
}
|
|
|
|
fn serialize_none(self) -> Result<Self::Ok> {
|
|
Ok(Value::simple_record0("None").wrap())
|
|
}
|
|
|
|
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
Ok(Value::simple_record1("Some", to_value(v)).wrap())
|
|
}
|
|
|
|
fn serialize_unit(self) -> Result<Self::Ok> {
|
|
Ok(Value::simple_record0("tuple").wrap())
|
|
}
|
|
|
|
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
|
|
Ok(Value::simple_record0(name).wrap())
|
|
}
|
|
|
|
fn serialize_unit_variant(
|
|
self,
|
|
_name: &'static str,
|
|
_variant: u32,
|
|
variant_name: &'static str,
|
|
) -> Result<Self::Ok> {
|
|
Ok(Value::simple_record0(variant_name).wrap())
|
|
}
|
|
|
|
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
match super::magic::receive_output_value(name, value) {
|
|
Some(v) => Ok(v),
|
|
None => {
|
|
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
|
|
Ok(Value::simple_record1(name, to_value(value)).wrap())
|
|
}
|
|
}
|
|
}
|
|
|
|
fn serialize_newtype_variant<T: ?Sized>(
|
|
self,
|
|
_name: &'static str,
|
|
_variant: u32,
|
|
variant_name: &'static str,
|
|
value: &T,
|
|
) -> Result<Self::Ok>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
Ok(Value::simple_record1(variant_name, to_value(value)).wrap())
|
|
}
|
|
|
|
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
|
|
let vec = match count {
|
|
Some(n) => Vec::with_capacity(n),
|
|
None => Vec::new(),
|
|
};
|
|
Ok(SerializeSequence { vec })
|
|
}
|
|
|
|
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
|
|
Ok(SerializeRecord {
|
|
r: Value::simple_record("tuple", count),
|
|
})
|
|
}
|
|
|
|
fn serialize_tuple_struct(
|
|
self,
|
|
name: &'static str,
|
|
count: usize,
|
|
) -> Result<Self::SerializeTupleStruct> {
|
|
Ok(SerializeRecord {
|
|
r: Value::simple_record(name, count),
|
|
})
|
|
}
|
|
|
|
fn serialize_tuple_variant(
|
|
self,
|
|
_name: &'static str,
|
|
_variant: u32,
|
|
variant_name: &'static str,
|
|
count: usize,
|
|
) -> Result<Self::SerializeTupleVariant> {
|
|
Ok(SerializeRecord {
|
|
r: Value::simple_record(variant_name, count),
|
|
})
|
|
}
|
|
|
|
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
|
|
Ok(SerializeDictionary {
|
|
next_key: None,
|
|
items: Map::new(),
|
|
})
|
|
}
|
|
|
|
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
|
|
Ok(SerializeRecord {
|
|
r: Value::simple_record(name, count),
|
|
})
|
|
}
|
|
|
|
fn serialize_struct_variant(
|
|
self,
|
|
_name: &'static str,
|
|
_variant: u32,
|
|
variant_name: &'static str,
|
|
count: usize,
|
|
) -> Result<Self::SerializeStructVariant> {
|
|
Ok(SerializeRecord {
|
|
r: Value::simple_record(variant_name, count),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeMap for SerializeDictionary {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.next_key = Some(to_value(key));
|
|
Ok(())
|
|
}
|
|
|
|
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
let key = self.next_key.take().unwrap();
|
|
self.items.insert(key, to_value(value));
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(Value::from(self.items).wrap())
|
|
}
|
|
}
|
|
|
|
impl SerializeRecord {
|
|
fn push<T: ?Sized>(&mut self, value: &T)
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.r.fields_vec_mut().push(to_value(value))
|
|
}
|
|
|
|
fn finish(self) -> IOValue {
|
|
self.r.finish().wrap()
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeStruct for SerializeRecord {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.push(value);
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(self.finish())
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeStructVariant for SerializeRecord {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.push(value);
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(self.finish())
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeTuple for SerializeRecord {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.push(value);
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(self.finish())
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeTupleStruct for SerializeRecord {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.push(value);
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(self.finish())
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeTupleVariant for SerializeRecord {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.push(value);
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(self.finish())
|
|
}
|
|
}
|
|
|
|
impl serde::ser::SerializeSeq for SerializeSequence {
|
|
type Ok = IOValue;
|
|
type Error = Error;
|
|
|
|
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
|
|
where
|
|
T: Serialize,
|
|
{
|
|
self.vec.push(to_value(value));
|
|
Ok(())
|
|
}
|
|
|
|
fn end(self) -> Result<Self::Ok> {
|
|
Ok(Value::from(self.vec).wrap())
|
|
}
|
|
}
|
|
|
|
/// Convenience function for directly converting a Serde-serializable `T` to an [IOValue].
|
|
pub fn to_value<T>(value: T) -> IOValue
|
|
where
|
|
T: Serialize,
|
|
{
|
|
value.serialize(Serializer).unwrap()
|
|
}
|