1use serde::Deserialize;
10use serde::Serialize;
11use serde::de::DeserializeOwned;
12use typeuri::Named;
13
14use crate::Part;
15use crate::part::BincodeDeserializer;
16use crate::part::BincodeSerializer;
17
18pub trait PartCodec: Sized
20where
21 Self::Repr: Serialize + DeserializeOwned + Named,
22 for<'a> Self::Repr: std::convert::TryFrom<&'a Self, Error = crate::Error>,
23 Self: std::convert::TryFrom<Self::Repr, Error = crate::Error>,
24{
25 type Repr;
27
28 fn to_repr(&self) -> crate::Result<Self::Repr> {
30 Self::Repr::try_from(self)
31 }
32
33 fn from_repr(repr: Self::Repr) -> crate::Result<Self> {
35 Self::try_from(repr)
36 }
37
38 fn to_part(&self) -> crate::Result<Part> {
40 Part::serialize(&self.to_repr()?)
41 }
42
43 fn from_part(part: Part) -> crate::Result<Self> {
45 let repr = part.deserialized::<Self::Repr>()?;
46 Self::from_repr(repr)
47 }
48}
49
50pub fn serialize_part_codec<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
52where
53 T: PartCodec,
54 S: serde::Serializer,
55{
56 <T as PartCodecSerializer<S>>::serialize(value, serializer)
57}
58
59pub fn deserialize_part_codec<'de, T, D>(deserializer: D) -> Result<T, D::Error>
61where
62 T: PartCodec,
63 D: serde::Deserializer<'de>,
64{
65 <T as PartCodecDeserializer<'de, D>>::deserialize(deserializer)
66}
67
68trait PartCodecSerializer<S: serde::Serializer> {
69 fn serialize(this: &Self, serializer: S) -> Result<S::Ok, S::Error>;
70}
71
72impl<T, S> PartCodecSerializer<S> for T
73where
74 T: PartCodec,
75 S: serde::Serializer,
76{
77 default fn serialize(this: &Self, serializer: S) -> Result<S::Ok, S::Error> {
78 this.to_repr()
79 .map_err(serde::ser::Error::custom)?
80 .serialize(serializer)
81 }
82}
83
84impl<'a, T> PartCodecSerializer<&'a mut BincodeSerializer> for T
85where
86 T: PartCodec,
87{
88 fn serialize(this: &Self, serializer: &'a mut BincodeSerializer) -> Result<(), bincode::Error> {
89 let part = this
90 .to_part()
91 .map_err(<bincode::Error as serde::ser::Error>::custom)?;
92 serializer.serialize_part(&part);
93 Ok(())
94 }
95}
96
97trait PartCodecDeserializer<'de, D: serde::Deserializer<'de>>: Sized {
98 fn deserialize(deserializer: D) -> Result<Self, D::Error>;
99}
100
101impl<'de, T, D> PartCodecDeserializer<'de, D> for T
102where
103 T: PartCodec,
104 D: serde::Deserializer<'de>,
105{
106 default fn deserialize(deserializer: D) -> Result<Self, D::Error> {
107 let repr = T::Repr::deserialize(deserializer)?;
108 T::from_repr(repr).map_err(serde::de::Error::custom)
109 }
110}
111
112impl<'a, T> PartCodecDeserializer<'_, &'a mut BincodeDeserializer> for T
113where
114 T: PartCodec,
115{
116 fn deserialize(deserializer: &'a mut BincodeDeserializer) -> Result<Self, bincode::Error> {
117 let part = deserializer.deserialize_part()?;
118 T::from_part(part).map_err(<bincode::Error as serde::de::Error>::custom)
119 }
120}
121
122#[macro_export]
124macro_rules! part_codec {
125 (
126 impl <$($impl_generics:ident),+> $ty:ty
127 {
128 type Repr = $repr:ty;
129 }
130 ) => {
131 $crate::part_codec! {
132 @expand
133 [<$($impl_generics),+>]
134 [<'de, $($impl_generics),+>]
135 [$ty]
136 [$repr]
137 }
138 };
139
140 (
141 impl $ty:ty
142 {
143 type Repr = $repr:ty;
144 }
145 ) => {
146 $crate::part_codec! {
147 @expand
148 []
149 [<'de>]
150 [$ty]
151 [$repr]
152 }
153 };
154
155 (
156 @expand
157 [$($impl_generics:tt)*]
158 [$($de_impl_generics:tt)*]
159 [$ty:ty]
160 [$repr:ty]
161 ) => {
162 impl $($impl_generics)* $crate::PartCodec for $ty
163 where
164 $repr: serde::Serialize + serde::de::DeserializeOwned + typeuri::Named,
165 for<'a> $repr: std::convert::TryFrom<&'a $ty, Error = $crate::Error>,
166 $ty: std::convert::TryFrom<$repr, Error = $crate::Error>,
167 {
168 type Repr = $repr;
169 }
170
171 impl $($impl_generics)* serde::Serialize for $ty
172 where
173 $ty: $crate::PartCodec,
174 {
175 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
176 where
177 S: serde::Serializer,
178 {
179 $crate::serialize_part_codec(self, serializer)
180 }
181 }
182
183 impl $($de_impl_generics)* serde::Deserialize<'de> for $ty
184 where
185 $ty: $crate::PartCodec,
186 {
187 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
188 where
189 D: serde::Deserializer<'de>,
190 {
191 $crate::deserialize_part_codec(deserializer)
192 }
193 }
194 };
195}