#![deny(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
extern crate alloc;
mod add_ref;
mod array;
mod bytes;
mod cell;
mod codec;
mod convert;
#[cfg(feature = "alloc")]
mod cow;
mod fold;
mod from;
mod human;
mod identity;
mod into;
mod map;
mod map_as_seq;
#[cfg(feature = "std")]
mod mutex;
mod option;
mod ptr;
mod range;
mod result;
mod reverse;
#[cfg(feature = "std")]
mod rwlock;
mod seq_as_map;
mod sequence;
mod str;
mod try_from;
mod try_into;
mod wrapping;
pub use add_ref::AddRef;
pub use array::Array;
#[cfg(feature = "alloc")]
pub use bytes::ByteVec;
pub use bytes::Bytes;
pub use cell::Cell;
pub use codec::Codec;
pub use convert::{Convert, RefConvert, RefTryConvert, TryConvert};
#[cfg(feature = "alloc")]
pub use cow::Cow;
pub use fold::Fold;
pub use from::From;
pub use human::HumanOr;
pub use identity::Id;
pub use into::Into;
pub use map::Map;
pub use map_as_seq::MapAsSeq;
#[cfg(feature = "std")]
pub use mutex::Mutex;
pub use option::Option;
pub use ptr::Ptr;
pub use range::Range;
pub use result::Result;
pub use reverse::Reverse;
#[cfg(feature = "std")]
pub use rwlock::RwLock;
pub use seq_as_map::SeqAsMap;
pub use sequence::Seq;
pub use str::Str;
pub use try_from::TryFrom;
pub use try_into::TryInto;
pub use wrapping::Wrapping;
use core::marker::PhantomData;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub trait SerializeWith<T: ?Sized> {
fn serialize_with<S: Serializer>(
value: &T,
serializer: S,
) -> core::result::Result<S::Ok, S::Error>;
}
pub trait DeserializeWith<'de, T> {
fn deserialize_with<D>(deserializer: D) -> core::result::Result<T, D::Error>
where
D: Deserializer<'de>;
}
impl<F, T> SerializeWith<&T> for &F
where
F: SerializeWith<T>,
T: ?Sized,
{
fn serialize_with<S: Serializer>(
value: &&T,
serializer: S,
) -> core::result::Result<S::Ok, S::Error> {
F::serialize_with(*value, serializer)
}
}
impl<F, T> SerializeWith<&mut T> for &F
where
F: SerializeWith<T>,
T: ?Sized,
{
fn serialize_with<S: Serializer>(
value: &&mut T,
serializer: S,
) -> core::result::Result<S::Ok, S::Error> {
F::serialize_with(*value, serializer)
}
}
pub struct WithEncoding<F, T: ?Sized> {
encoding: PhantomData<F>,
value: T,
}
impl<F, T> WithEncoding<F, T> {
pub fn into_inner(self) -> T {
self.value
}
}
impl<F, T> core::convert::From<T> for WithEncoding<F, T> {
fn from(value: T) -> Self {
Self {
encoding: PhantomData,
value,
}
}
}
impl<F, T> Serialize for WithEncoding<F, T>
where
F: SerializeWith<T>,
T: ?Sized,
{
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
F::serialize_with(&self.value, serializer)
}
}
impl<'de, F, T> Deserialize<'de> for WithEncoding<F, T>
where
F: DeserializeWith<'de, T>,
{
fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
F::deserialize_with(deserializer).map(|x| x.into())
}
}
macro_rules! impl_tuple {
($($types:ident $adapters:ident $xs:ident,)*) => {
impl<$($types, $adapters),*> SerializeWith<($($types,)*)> for ($($adapters,)*)
where
$($adapters: SerializeWith<$types>,)*
{
fn serialize_with<S: Serializer>(
value: &($($types,)*),
serializer: S,
) -> core::result::Result<S::Ok, S::Error> {
let ($($xs,)*) = value;
Serialize::serialize(
&($(WithEncoding::<&$adapters, _>::from($xs),)*),
serializer,
)
}
}
impl<'de, $($types, $adapters),*> DeserializeWith<'de, ($($types,)*)> for ($($adapters,)*)
where
$($adapters: DeserializeWith<'de, $types>,)*
{
fn deserialize_with<D>(deserializer: D) -> core::result::Result<($($types,)*), D::Error>
where
D: Deserializer<'de>,
{
let ($($xs,)*) = <($(WithEncoding<$adapters, $types>,)*) as Deserialize>::deserialize(deserializer)?;
Ok(($($xs.value,)*))
}
}
};
}
macro_rules! impl_tuples {
(
$($tys:ident $adapters:ident $xs:ident,)*
@ $ty_head:ident $adapter_head:ident $x_head:ident, $($ty_tail:ident $adapter_tail:ident $x_tail:ident,)*
) => {
impl_tuple!($($tys $adapters $xs,)*);
impl_tuples!($($tys $adapters $xs,)* $ty_head $adapter_head $x_head, @ $($ty_tail $adapter_tail $x_tail,)*);
};
($($tys:ident $adapters:ident $xs:ident,)* @) => {
impl_tuple!($($tys $adapters $xs,)*);
};
($($tys:ident $adapters:ident $xs:ident,)*) => {
impl_tuples!(@ $($tys $adapters $xs,)*);
};
}
impl_tuples!(
T0 A0 x0,
T1 A1 x1,
T2 A2 x2,
T3 A3 x3,
T4 A4 x4,
T5 A5 x5,
T6 A6 x6,
T7 A7 x7,
T8 A8 x8,
T9 A9 x9,
T10 A10 x10,
T11 A11 x11,
T12 A12 x12,
T13 A13 x13,
T14 A14 x14,
T15 A15 x15,
);
#[cfg(test)]
mod test_utils {
use core::fmt::Debug;
use serde::{de::DeserializeOwned, Serialize};
use serde_json::Value;
#[track_caller]
pub(crate) fn check_serialization<T>(x: T, expected: Value)
where
T: PartialEq + Debug + Serialize + DeserializeOwned,
{
let actual = serde_json::to_value(&x).unwrap();
assert_eq!(actual, expected);
let deserialized = serde_json::from_value::<T>(actual).unwrap();
assert_eq!(x, deserialized);
}
}