diff --git a/src/ipld.rs b/src/ipld.rs index ff0b9f7..a9b54fa 100644 --- a/src/ipld.rs +++ b/src/ipld.rs @@ -33,30 +33,103 @@ impl fmt::Display for IndexError { #[cfg(feature = "std")] impl std::error::Error for IndexError {} -/// Ipld +/// Define the primitive types used for the internal IPLD Data Model representation within Rust. +/// +/// `Null` is missing as this is always represented as a unit variant. The container types are +/// derived from the primitives defined here. +pub trait Primitives: fmt::Debug { + /// Type for a boolean. + type Bool: fmt::Debug + From + Into + Copy; + /// Type for an integer. + type Integer: fmt::Debug + From + From + From + Into + Copy; + /// Type for a float. + type Float: fmt::Debug + From + Into + Copy; + /// Type for a String. + #[cfg(not(feature = "serde"))] + type String: fmt::Debug + From + Into + Ord; + // TODO vmx 2024-08-14: Check if the `for <'de>` is the right thing to do here. + #[cfg(feature = "serde")] + type String: fmt::Debug + + From + + Into + + Ord + + for<'de> serde::Deserialize<'de> + + serde::Serialize; + /// Type for bytes. + type Bytes: fmt::Debug + From> + Into>; + /// Type for a link. + // TODO vmx 2024-08-14: This should be `CidGeneric` and not just `Cid`. + #[cfg(not(feature = "serde"))] + type Link: fmt::Debug + fmt::Display + From + Into; + #[cfg(feature = "serde")] + type Link: fmt::Debug + fmt::Display + From + Into + serde::Serialize; +} + +/// The default values for the primitive types. +#[derive(Clone, Debug)] +//pub struct DefaultPrimitives<'de>(&'de PhantomData<_>); +pub struct DefaultPrimitives; + +impl Primitives for DefaultPrimitives { + type Bool = bool; + type Integer = i128; + type Float = f64; + type String = String; + type Bytes = Vec; + type Link = Cid; +} + +#[cfg(feature = "serde")] +pub trait PrimitivesSerde<'de>: Primitives { + fn visit_integer, E: serde::de::Error>( + visitor: V, + value: ::Integer, + ) -> Result; +} + +#[cfg(feature = "serde")] +impl<'de> PrimitivesSerde<'de> for DefaultPrimitives { + //fn visit_integer(visitor: V) -> Result + fn visit_integer(visitor: V, value: Self::Integer) -> Result + where + V: serde::de::Visitor<'de>, + E: serde::de::Error, + { + visitor.visit_i128(value) + //println!("vmx: visit_integer") + } +} + +/// The generic version of the core IPLD type that allows using custom primitive types. #[derive(Clone)] -pub enum Ipld { +pub enum IpldGeneric { /// Represents the absence of a value or the value undefined. Null, /// Represents a boolean value. - Bool(bool), + Bool(P::Bool), /// Represents an integer. - Integer(i128), + Integer(P::Integer), /// Represents a floating point value. - Float(f64), + Float(P::Float), /// Represents an UTF-8 string. - String(String), + String(P::String), /// Represents a sequence of bytes. - Bytes(Vec), + Bytes(P::Bytes), /// Represents a list. - List(Vec), + List(Vec), /// Represents a map of strings. - Map(BTreeMap), - /// Represents a map of integers. - Link(Cid), + Map(BTreeMap), + /// Represents a link, usually a CID. + Link(P::Link), } -impl fmt::Debug for Ipld { +/// The core IPLD type. +pub type Ipld = IpldGeneric; + +impl

fmt::Debug for IpldGeneric

+where + P: Primitives, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if f.alternate() { match self { diff --git a/src/lib.rs b/src/lib.rs index 0190253..3fd2f09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ +#![allow(clippy::needless_doctest_main)] #![doc = include_str!("../README.md")] -#![deny(missing_docs)] -#![deny(warnings)] +//#![deny(missing_docs)] +//#![deny(warnings)] #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; diff --git a/src/serde/de.rs b/src/serde/de.rs index cd890a6..310e200 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -1,5 +1,5 @@ use alloc::{borrow::ToOwned, collections::BTreeMap, format, string::String, vec::Vec}; -use core::{convert::TryFrom, fmt}; +use core::{convert::TryFrom, fmt, marker::PhantomData}; use cid::serde::{BytesToCidVisitor, CID_SERDE_PRIVATE_IDENTIFIER}; use cid::Cid; @@ -8,9 +8,12 @@ use serde::{ forward_to_deserialize_any, Deserialize, }; -use crate::{ipld::Ipld, serde::SerdeError}; +use crate::{ + ipld::{IpldGeneric, Primitives, PrimitivesSerde}, + serde::SerdeError, +}; -/// Deserialize instances of [`crate::ipld::Ipld`]. +/// Deserialize instances of [`crate::ipld::IpldGeneric`]. /// /// # Example /// @@ -48,22 +51,35 @@ use crate::{ipld::Ipld, serde::SerdeError}; /// assert!(matches!(person, Ok(Person { .. }))); /// ``` // NOTE vmx 2021-12-22: Taking by value is also what `serde_json` does. -pub fn from_ipld(value: Ipld) -> Result +pub fn from_ipld(value: IpldGeneric

) -> Result where + P: for<'de> PrimitivesSerde<'de>, T: serde::de::DeserializeOwned, { T::deserialize(value) } -impl<'de> de::Deserialize<'de> for Ipld { +//impl<'de, P> de::Deserializer<'de> for IpldGeneric

{ +// where +// P: Primitives, +// P::Integer: SomeTrait<'de>, + +impl<'de, P> de::Deserialize<'de> for IpldGeneric

+where + P: PrimitivesSerde<'de>, + //P::Integer: TraitWithDeLifetime<'de>, +{ fn deserialize(deserializer: D) -> Result where D: de::Deserializer<'de>, { - struct IpldVisitor; + struct IpldVisitor(PhantomData); - impl<'de> de::Visitor<'de> for IpldVisitor { - type Value = Ipld; + impl<'de, PInner> de::Visitor<'de> for IpldVisitor + where + PInner: PrimitivesSerde<'de>, + { + type Value = IpldGeneric; fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.write_str("any valid IPLD kind") @@ -74,7 +90,9 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::String(String::from(value))) + //Ok(IpldGeneric::String(PInner::String::from(value))) + //Ok(IpldGeneric::String(PInner::String::from(value.to_string()))) + Ok(IpldGeneric::String(value.to_string().into())) } #[inline] @@ -90,7 +108,8 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Bytes(v)) + //Ok(IpldGeneric::Bytes(PInner::Bytes ::from(v))) + Ok(IpldGeneric::Bytes(v.into())) } #[inline] @@ -98,7 +117,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Integer(v.into())) + Ok(IpldGeneric::Integer(v.into())) } #[inline] @@ -106,7 +125,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Integer(v.into())) + Ok(IpldGeneric::Integer(v.into())) } #[inline] @@ -114,7 +133,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Integer(v)) + Ok(IpldGeneric::Integer(v.into())) } #[inline] @@ -122,7 +141,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Float(v)) + Ok(IpldGeneric::Float(v.into())) } #[inline] @@ -130,7 +149,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Bool(v)) + Ok(IpldGeneric::Bool(v.into())) } #[inline] @@ -138,7 +157,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Null) + Ok(IpldGeneric::Null) } #[inline] @@ -154,7 +173,7 @@ impl<'de> de::Deserialize<'de> for Ipld { where E: de::Error, { - Ok(Ipld::Null) + Ok(IpldGeneric::Null) } #[inline] @@ -168,7 +187,7 @@ impl<'de> de::Deserialize<'de> for Ipld { vec.push(elem); } - Ok(Ipld::List(vec)) + Ok(IpldGeneric::List(vec)) } #[inline] @@ -185,7 +204,7 @@ impl<'de> de::Deserialize<'de> for Ipld { } } - Ok(Ipld::Map(values)) + Ok(IpldGeneric::Map(values)) } /// Newtype structs are only used to deserialize CIDs. @@ -196,11 +215,11 @@ impl<'de> de::Deserialize<'de> for Ipld { { deserializer .deserialize_bytes(BytesToCidVisitor) - .map(Ipld::Link) + .map(|link| IpldGeneric::Link(link.into())) } } - deserializer.deserialize_any(IpldVisitor) + deserializer.deserialize_any(IpldVisitor(PhantomData)) } } @@ -208,15 +227,15 @@ macro_rules! impl_deserialize_integer { ($ty:ident, $deserialize:ident, $visit:ident) => { fn $deserialize>(self, visitor: V) -> Result { match self { - Self::Integer(integer) => match $ty::try_from(integer) { + Self::Integer(integer) => match $ty::try_from(integer.into()) { Ok(int) => visitor.$visit(int), Err(_) => error(format!( - "`Ipld::Integer` value was bigger than `{}`", + "`IpldGeneric::Integer` value was bigger than `{}`", stringify!($ty) )), }, _ => error(format!( - "Only `Ipld::Integer` can be deserialized to `{}`, input was `{:#?}`", + "Only `IpldGeneric::Integer` can be deserialized to `{}`, input was `{:#?}`", stringify!($ty), self )), @@ -227,8 +246,8 @@ macro_rules! impl_deserialize_integer { /// A Deserializer for CIDs. /// -/// A separate deserializer is needed to make sure we always deserialize only CIDs as `Ipld::Link` -/// and don't deserialize arbitrary bytes. +/// A separate deserializer is needed to make sure we always deserialize only CIDs as +/// `IpldGeneric::Link` and don't deserialize arbitrary bytes. struct CidDeserializer(Cid); impl<'de> de::Deserializer<'de> for CidDeserializer { @@ -249,13 +268,16 @@ impl<'de> de::Deserializer<'de> for CidDeserializer { } } -/// Deserialize from an [`Ipld`] enum into a Rust type. +/// Deserialize from an [`IpldGeneric`] enum into a Rust type. /// /// The deserialization will return an error if you try to deserialize into an integer type that -/// would be too small to hold the value stored in [`Ipld::Integer`]. +/// would be too small to hold the value stored in [`IpldGeneric::Integer`]. /// -/// [`Ipld::Floats`] can be converted to `f32` if there is no of precision, else it will error. -impl<'de> de::Deserializer<'de> for Ipld { +/// [`IpldGeneric::Floats`] can be converted to `f32` if there is no of precision, else it will error. +impl<'de, P> de::Deserializer<'de> for IpldGeneric

+where + P: PrimitivesSerde<'de>, +{ type Error = SerdeError; #[inline] @@ -265,14 +287,16 @@ impl<'de> de::Deserializer<'de> for Ipld { { match self { Self::Null => visitor.visit_none(), - Self::Bool(bool) => visitor.visit_bool(bool), - Self::Integer(i128) => visitor.visit_i128(i128), - Self::Float(f64) => visitor.visit_f64(f64), - Self::String(string) => visitor.visit_str(&string), - Self::Bytes(bytes) => visitor.visit_bytes(&bytes), + Self::Bool(bool) => visitor.visit_bool(bool.into()), + //GO ON HERE and think about what to visit here + //Self::Integer(i128) => visitor.visit_i128(i128), + Self::Integer(i128) => P::visit_integer(visitor, i128), + Self::Float(f64) => visitor.visit_f64(f64.into()), + Self::String(string) => visitor.visit_str(&string.into()), + Self::Bytes(bytes) => visitor.visit_bytes(&bytes.into()), Self::List(list) => visit_seq(list, visitor), Self::Map(map) => visit_map(map, visitor), - Self::Link(cid) => visitor.visit_newtype_struct(CidDeserializer(cid)), + Self::Link(cid) => visitor.visit_newtype_struct(CidDeserializer(cid.into())), } } @@ -288,7 +312,7 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_bool>(self, visitor: V) -> Result { match self { - Self::Bool(bool) => visitor.visit_bool(bool), + Self::Bool(bool) => visitor.visit_bool(bool.into()), _ => error(format!( "Only `Ipld::Bool` can be deserialized to bool, input was `{:#?}`", self @@ -308,7 +332,8 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_f32>(self, visitor: V) -> Result { match self { - Self::Float(float) => { + Self::Float(associate_float) => { + let float = associate_float.into(); if !float.is_finite() { error(format!("`Ipld::Float` must be a finite number, not infinity or NaN, input was `{}`", float)) } else if (float as f32) as f64 != float { @@ -328,7 +353,8 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_f64>(self, visitor: V) -> Result { match self { - Self::Float(float) => { + Self::Float(associate_float) => { + let float = associate_float.into(); if float.is_finite() { visitor.visit_f64(float) } else { @@ -344,7 +370,8 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_char>(self, visitor: V) -> Result { match self { - Self::String(string) => { + Self::String(associate_string) => { + let string: String = associate_string.into(); if string.chars().count() == 1 { visitor.visit_char(string.chars().next().unwrap()) } else { @@ -360,7 +387,7 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_str>(self, visitor: V) -> Result { match self { - Self::String(string) => visitor.visit_str(&string), + Self::String(string) => visitor.visit_str(&string.into()), _ => error(format!( "Only `Ipld::String` can be deserialized to string, input was `{:#?}`", self @@ -370,7 +397,7 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_string>(self, visitor: V) -> Result { match self { - Self::String(string) => visitor.visit_string(string), + Self::String(string) => visitor.visit_string(string.into()), _ => error(format!( "Only `Ipld::String` can be deserialized to string, input was `{:#?}`", self @@ -380,7 +407,7 @@ impl<'de> de::Deserializer<'de> for Ipld { fn deserialize_bytes>(self, visitor: V) -> Result { match self { - Self::Bytes(bytes) => visitor.visit_bytes(&bytes), + Self::Bytes(bytes) => visitor.visit_bytes(&bytes.into()), _ => error(format!( "Only `Ipld::Bytes` can be deserialized to bytes, input was `{:#?}`", self @@ -393,7 +420,7 @@ impl<'de> de::Deserializer<'de> for Ipld { visitor: V, ) -> Result { match self { - Self::Bytes(bytes) => visitor.visit_byte_buf(bytes), + Self::Bytes(bytes) => visitor.visit_byte_buf(bytes.into()), _ => error(format!( "Only `Ipld::Bytes` can be deserialized to bytes, input was `{:#?}`", self @@ -455,7 +482,7 @@ impl<'de> de::Deserializer<'de> for Ipld { visitor: V, ) -> Result { match self { - Self::String(string) => visitor.visit_str(&string), + Self::String(string) => visitor.visit_str(&string.into()), _ => error(format!( "Only `Ipld::String` can be deserialized to identifier, input was `{:#?}`", self @@ -493,7 +520,7 @@ impl<'de> de::Deserializer<'de> for Ipld { ) -> Result { if name == CID_SERDE_PRIVATE_IDENTIFIER { match self { - Ipld::Link(cid) => visitor.visit_newtype_struct(CidDeserializer(cid)), + IpldGeneric::Link(cid) => visitor.visit_newtype_struct(CidDeserializer(cid.into())), _ => error(format!( "Only `Ipld::Link`s can be deserialized to CIDs, input was `{:#?}`", self @@ -513,7 +540,7 @@ impl<'de> de::Deserializer<'de> for Ipld { visitor: V, ) -> Result { let (variant, value) = match self { - Ipld::Map(map) => { + IpldGeneric::Map(map) => { let mut iter = map.into_iter(); let (variant, value) = match iter.next() { Some(v) => v, @@ -529,9 +556,9 @@ impl<'de> de::Deserializer<'de> for Ipld { "Only `Ipld::Map`s with a single key can be deserialized to `enum`, input had more keys" ); } - (variant, Some(value)) + (variant.into(), Some(value)) } - Ipld::String(variant) => (variant, None), + IpldGeneric::String(variant) => (variant.into(), None), _ => return error(format!( "Only `Ipld::Map` and `Ipld::String` can be deserialized to `enum`, input was `{:#?}`", self @@ -563,16 +590,21 @@ impl<'de> de::Deserializer<'de> for Ipld { } } -fn visit_map<'de, V>(map: BTreeMap, visitor: V) -> Result +fn visit_map<'de, P, V>( + map: BTreeMap>, + visitor: V, +) -> Result where + P: PrimitivesSerde<'de>, V: de::Visitor<'de>, { let mut deserializer = MapDeserializer::new(map); visitor.visit_map(&mut deserializer) } -fn visit_seq<'de, V>(list: Vec, visitor: V) -> Result +fn visit_seq<'de, P, V>(list: Vec>, visitor: V) -> Result where + P: PrimitivesSerde<'de>, V: de::Visitor<'de>, { let mut deserializer = SeqDeserializer::new(list); @@ -581,13 +613,19 @@ where // Heavily based on // https://github.com/serde-rs/json/blob/95f67a09399d546d9ecadeb747a845a77ff309b2/src/value/de.rs#L601 -struct MapDeserializer { - iter: as IntoIterator>::IntoIter, - value: Option, +struct MapDeserializer

+where + P: Primitives, +{ + iter: > as IntoIterator>::IntoIter, + value: Option>, } -impl MapDeserializer { - fn new(map: BTreeMap) -> Self { +impl

MapDeserializer

+where + P: Primitives, +{ + fn new(map: BTreeMap>) -> Self { Self { iter: map.into_iter(), value: None, @@ -595,7 +633,10 @@ impl MapDeserializer { } } -impl<'de> de::MapAccess<'de> for MapDeserializer { +impl<'de, P> de::MapAccess<'de> for MapDeserializer

+where + P: PrimitivesSerde<'de>, +{ type Error = SerdeError; fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> @@ -605,7 +646,7 @@ impl<'de> de::MapAccess<'de> for MapDeserializer { match self.iter.next() { Some((key, value)) => { self.value = Some(value); - seed.deserialize(Ipld::String(key)).map(Some) + seed.deserialize(IpldGeneric::

::String(key)).map(Some) } None => Ok(None), } @@ -631,19 +672,28 @@ impl<'de> de::MapAccess<'de> for MapDeserializer { // Heavily based on // https://github.com/serde-rs/json/blob/95f67a09399d546d9ecadeb747a845a77ff309b2/src/value/de.rs#L554 -struct SeqDeserializer { - iter: as IntoIterator>::IntoIter, +struct SeqDeserializer

+where + P: Primitives, +{ + iter: > as IntoIterator>::IntoIter, } -impl SeqDeserializer { - fn new(vec: Vec) -> Self { +impl

SeqDeserializer

+where + P: Primitives, +{ + fn new(vec: Vec>) -> Self { Self { iter: vec.into_iter(), } } } -impl<'de> de::SeqAccess<'de> for SeqDeserializer { +impl<'de, P> de::SeqAccess<'de> for SeqDeserializer

+where + P: PrimitivesSerde<'de>, +{ type Error = SerdeError; fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> @@ -666,14 +716,20 @@ impl<'de> de::SeqAccess<'de> for SeqDeserializer { // Heavily based on // https://github.com/serde-rs/json/blob/95f67a09399d546d9ecadeb747a845a77ff309b2/src/value/de.rs#L455 -struct EnumDeserializer { +struct EnumDeserializer

+where + P: Primitives, +{ variant: String, - value: Option, + value: Option>, } -impl<'de> de::EnumAccess<'de> for EnumDeserializer { +impl<'de, P> de::EnumAccess<'de> for EnumDeserializer

+where + P: PrimitivesSerde<'de>, +{ type Error = SerdeError; - type Variant = VariantDeserializer; + type Variant = VariantDeserializer

; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where @@ -687,9 +743,12 @@ impl<'de> de::EnumAccess<'de> for EnumDeserializer { // Heavily based on // https://github.com/serde-rs/json/blob/95f67a09399d546d9ecadeb747a845a77ff309b2/src/value/de.rs#L482 -struct VariantDeserializer(Option); +struct VariantDeserializer(Option>); -impl<'de> de::VariantAccess<'de> for VariantDeserializer { +impl<'de, P> de::VariantAccess<'de> for VariantDeserializer

+where + P: PrimitivesSerde<'de>, +{ type Error = SerdeError; fn unit_variant(self) -> Result<(), Self::Error> { @@ -717,7 +776,7 @@ impl<'de> de::VariantAccess<'de> for VariantDeserializer { V: de::Visitor<'de>, { match self.0 { - Some(Ipld::List(list)) => { + Some(IpldGeneric::List(list)) => { if len == list.len() { visit_seq(list, visitor) } else { @@ -744,7 +803,7 @@ impl<'de> de::VariantAccess<'de> for VariantDeserializer { V: de::Visitor<'de>, { match self.0 { - Some(Ipld::Map(v)) => visit_map(v, visitor), + Some(IpldGeneric::Map(v)) => visit_map(v, visitor), Some(_) => error(format!( "Only `Ipld::Map` can be deserialized to struct variant, input was `{:#?}`", self.0 diff --git a/src/serde/ser.rs b/src/serde/ser.rs index 19998f2..d039dd5 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -7,13 +7,16 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use core::convert::TryFrom; +use core::{convert::TryFrom, fmt::Debug, marker::PhantomData}; use cid::serde::CID_SERDE_PRIVATE_IDENTIFIER; use cid::Cid; use serde::ser; -use crate::{ipld::Ipld, serde::SerdeError}; +use crate::{ + ipld::{IpldGeneric, Primitives}, + serde::SerdeError, +}; /// Serialize into instances of [`crate::ipld::Ipld`]. /// @@ -72,50 +75,68 @@ use crate::{ipld::Ipld, serde::SerdeError}; /// let ipld = to_ipld(person); /// assert!(matches!(ipld, Ok(Ipld::Map(_)))); /// ``` -pub fn to_ipld(value: T) -> Result +pub fn to_ipld(value: T) -> Result, SerdeError> where T: ser::Serialize, + P: Primitives, { - value.serialize(Serializer) + value.serialize(Serializer::new()) } -impl ser::Serialize for Ipld { +impl

ser::Serialize for IpldGeneric

+where + P: Primitives, + //for<'a> &'a [u8]: From<&'a P::Bytes>, + //for<'a> &'a str: From<&'a P::String>, +{ fn serialize(&self, serializer: S) -> Result where S: ser::Serializer, { match &self { Self::Null => serializer.serialize_none(), - Self::Bool(value) => serializer.serialize_bool(*value), - Self::Integer(value) => serializer.serialize_i128(*value), - Self::Float(value) => serializer.serialize_f64(*value), - Self::String(value) => serializer.serialize_str(value), - Self::Bytes(value) => serializer.serialize_bytes(value), + Self::Bool(value) => serializer.serialize_bool((*value).into()), + Self::Integer(value) => serializer.serialize_i128((*value).into()), + Self::Float(value) => serializer.serialize_f64((*value).into()), + Self::String(value) => serializer.serialize_str(value.into()), + Self::Bytes(value) => serializer.serialize_bytes(value.into()), Self::List(value) => serializer.collect_seq(value), - Self::Map(value) => serializer.collect_map(value), + Self::Map(value) => { + serializer.collect_map::<_, _, &BTreeMap>>(value) + } Self::Link(value) => value.serialize(serializer), + //_ => todo!(), } } } /// The IPLD serializer. -pub struct Serializer; +pub struct Serializer

(PhantomData

); -impl serde::Serializer for Serializer { - type Ok = Ipld; +impl

Serializer

{ + pub fn new() -> Self { + Self(PhantomData) + } +} + +impl

serde::Serializer for Serializer

+where + P: Primitives + Debug, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - type SerializeSeq = SerializeVec; - type SerializeTuple = SerializeVec; - type SerializeTupleStruct = SerializeVec; - type SerializeTupleVariant = SerializeTupleVariant; - type SerializeMap = SerializeMap; - type SerializeStruct = SerializeMap; - type SerializeStructVariant = SerializeStructVariant; + type SerializeSeq = SerializeVec

; + type SerializeTuple = SerializeVec

; + type SerializeTupleStruct = SerializeVec

; + type SerializeTupleVariant = SerializeTupleVariant

; + type SerializeMap = SerializeMap

; + type SerializeStruct = SerializeMap

; + type SerializeStructVariant = SerializeStructVariant

; #[inline] fn serialize_bool(self, value: bool) -> Result { - Ok(Self::Ok::Bool(value)) + Ok(Self::Ok::Bool(value.into())) } #[inline] @@ -139,7 +160,7 @@ impl serde::Serializer for Serializer { } fn serialize_i128(self, value: i128) -> Result { - Ok(Self::Ok::Integer(value)) + Ok(Self::Ok::Integer(value.into())) } #[inline] @@ -169,7 +190,7 @@ impl serde::Serializer for Serializer { #[inline] fn serialize_f64(self, value: f64) -> Result { - Ok(Self::Ok::Float(value)) + Ok(Self::Ok::Float(value.into())) } #[inline] @@ -179,11 +200,11 @@ impl serde::Serializer for Serializer { #[inline] fn serialize_str(self, value: &str) -> Result { - Ok(Self::Ok::String(value.to_owned())) + Ok(Self::Ok::String(value.to_owned().into())) } fn serialize_bytes(self, value: &[u8]) -> Result { - Ok(Self::Ok::Bytes(value.to_vec())) + Ok(Self::Ok::Bytes(value.to_vec().into())) } #[inline] @@ -207,26 +228,26 @@ impl serde::Serializer for Serializer { } #[inline] - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, name: &'static str, value: &T, ) -> Result where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { let ipld = value.serialize(self); if name == CID_SERDE_PRIVATE_IDENTIFIER { - if let Ok(Ipld::Bytes(bytes)) = ipld { - let cid = Cid::try_from(bytes) + if let Ok(IpldGeneric::Bytes(bytes)) = ipld { + let cid = Cid::try_from(bytes.into()) .map_err(|err| ser::Error::custom(format!("Invalid CID: {}", err)))?; - return Ok(Self::Ok::Link(cid)); + return Ok(Self::Ok::Link(cid.into())); } } ipld } - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, @@ -234,9 +255,9 @@ impl serde::Serializer for Serializer { value: &T, ) -> Result where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { - let values = BTreeMap::from([(variant.to_owned(), value.serialize(self)?)]); + let values = BTreeMap::from([(variant.to_owned().into(), value.serialize(self)?)]); Ok(Self::Ok::Map(values)) } @@ -246,9 +267,9 @@ impl serde::Serializer for Serializer { } #[inline] - fn serialize_some(self, value: &T) -> Result + fn serialize_some(self, value: &T) -> Result where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { value.serialize(self) } @@ -307,7 +328,7 @@ impl serde::Serializer for Serializer { _len: usize, ) -> Result { Ok(SerializeStructVariant { - name: String::from(variant), + name: P::String::from(variant.into()), map: BTreeMap::new(), }) } @@ -318,34 +339,49 @@ impl serde::Serializer for Serializer { } } -pub struct SerializeVec { - vec: Vec, +pub struct SerializeVec

+where + P: Primitives, +{ + vec: Vec>, } -pub struct SerializeTupleVariant { +pub struct SerializeTupleVariant

+where + P: Primitives, +{ name: String, - vec: Vec, + vec: Vec>, } -pub struct SerializeMap { - map: BTreeMap, - next_key: Option, +pub struct SerializeMap

+where + P: Primitives, +{ + map: BTreeMap>, + next_key: Option, } -pub struct SerializeStructVariant { - name: String, - map: BTreeMap, +pub struct SerializeStructVariant

+where + P: Primitives, +{ + name: P::String, + map: BTreeMap>, } -impl ser::SerializeSeq for SerializeVec { - type Ok = Ipld; +impl

ser::SerializeSeq for SerializeVec

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { - self.vec.push(value.serialize(Serializer)?); + self.vec.push(value.serialize(Serializer::new())?); Ok(()) } @@ -354,13 +390,16 @@ impl ser::SerializeSeq for SerializeVec { } } -impl ser::SerializeTuple for SerializeVec { - type Ok = Ipld; +impl

ser::SerializeTuple for SerializeVec

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { ser::SerializeSeq::serialize_element(self, value) } @@ -370,13 +409,16 @@ impl ser::SerializeTuple for SerializeVec { } } -impl ser::SerializeTupleStruct for SerializeVec { - type Ok = Ipld; +impl

ser::SerializeTupleStruct for SerializeVec

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { ser::SerializeSeq::serialize_element(self, value) } @@ -386,34 +428,40 @@ impl ser::SerializeTupleStruct for SerializeVec { } } -impl ser::SerializeTupleVariant for SerializeTupleVariant { - type Ok = Ipld; +impl

ser::SerializeTupleVariant for SerializeTupleVariant

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { - self.vec.push(value.serialize(Serializer)?); + self.vec.push(value.serialize(Serializer::new())?); Ok(()) } fn end(self) -> Result { - let map = BTreeMap::from([(self.name, Self::Ok::List(self.vec))]); + let map = BTreeMap::from([(self.name.into(), Self::Ok::List(self.vec))]); Ok(Self::Ok::Map(map)) } } -impl ser::SerializeMap for SerializeMap { - type Ok = Ipld; +impl

ser::SerializeMap for SerializeMap

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { - match key.serialize(Serializer)? { - Ipld::String(string_key) => { + match key.serialize(Serializer::

::new())? { + IpldGeneric::String(string_key) => { self.next_key = Some(string_key); Ok(()) } @@ -421,15 +469,15 @@ impl ser::SerializeMap for SerializeMap { } } - fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { let key = self.next_key.take(); // Panic because this indicates a bug in the program rather than an // expected failure. let key = key.expect("serialize_value called before serialize_key"); - self.map.insert(key, value.serialize(Serializer)?); + self.map.insert(key, value.serialize(Serializer::new())?); Ok(()) } @@ -438,17 +486,16 @@ impl ser::SerializeMap for SerializeMap { } } -impl ser::SerializeStruct for SerializeMap { - type Ok = Ipld; +impl

ser::SerializeStruct for SerializeMap

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_field( - &mut self, - key: &'static str, - value: &T, - ) -> Result<(), Self::Error> + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { serde::ser::SerializeMap::serialize_key(self, key)?; serde::ser::SerializeMap::serialize_value(self, value) @@ -459,20 +506,19 @@ impl ser::SerializeStruct for SerializeMap { } } -impl ser::SerializeStructVariant for SerializeStructVariant { - type Ok = Ipld; +impl

ser::SerializeStructVariant for SerializeStructVariant

+where + P: Primitives, +{ + type Ok = IpldGeneric

; type Error = SerdeError; - fn serialize_field( - &mut self, - key: &'static str, - value: &T, - ) -> Result<(), Self::Error> + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where - T: ser::Serialize, + T: ser::Serialize + ?Sized, { self.map - .insert(key.to_string(), value.serialize(Serializer)?); + .insert(key.to_string().into(), value.serialize(Serializer::new())?); Ok(()) } diff --git a/tests/serde_serializer.rs b/tests/serde_serializer.rs index 56952c4..6967dc5 100644 --- a/tests/serde_serializer.rs +++ b/tests/serde_serializer.rs @@ -25,7 +25,7 @@ where #[allow(clippy::let_unit_value)] fn ipld_serializer_unit() { let unit = (); - let serialized = to_ipld(unit); + let serialized: Result = to_ipld(unit); assert!(serialized.is_err()); } @@ -35,7 +35,7 @@ fn ipld_serializer_unit_struct() { struct UnitStruct; let unit_struct = UnitStruct; - let serialized = to_ipld(unit_struct); + let serialized: Result = to_ipld(unit_struct); assert!(serialized.is_err()); }