1use std::{error::Error, fmt, io, io::Write, ops};
2
3pub use nimiq_serde_derive::{SerializedMaxSize, SerializedSize};
4pub use postcard::{fixint, FixedSizeByteArray};
5use serde::{
6 de::{Deserializer, Error as _},
7 ser::Serializer,
8};
9pub use serde_derive::{Deserialize, Serialize};
10
11#[derive(Eq, PartialEq)]
16pub struct DeserializeError(DeserializeErrorInner);
17
18#[derive(Eq, PartialEq)]
19enum DeserializeErrorInner {
20 Postcard(postcard::Error),
21 ExtraData,
22}
23
24impl DeserializeError {
25 fn from(error: postcard::Error) -> DeserializeError {
26 DeserializeError(DeserializeErrorInner::Postcard(error))
27 }
28
29 pub fn bad_enum() -> DeserializeError {
31 DeserializeError(DeserializeErrorInner::Postcard(
32 postcard::Error::DeserializeBadEnum,
33 ))
34 }
35 pub fn unexpected_end() -> DeserializeError {
37 DeserializeError(DeserializeErrorInner::Postcard(
38 postcard::Error::DeserializeUnexpectedEnd,
39 ))
40 }
41 pub fn bad_encoding() -> DeserializeError {
43 DeserializeError(DeserializeErrorInner::Postcard(
44 postcard::Error::DeserializeBadEncoding,
45 ))
46 }
47 pub fn serde_custom() -> DeserializeError {
49 DeserializeError(DeserializeErrorInner::Postcard(
50 postcard::Error::SerdeDeCustom,
51 ))
52 }
53 pub fn extra_data() -> DeserializeError {
55 DeserializeError(DeserializeErrorInner::ExtraData)
56 }
57}
58
59impl fmt::Debug for DeserializeError {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 match &self.0 {
62 DeserializeErrorInner::Postcard(inner) => inner.fmt(f),
63 DeserializeErrorInner::ExtraData => f.debug_tuple("ExtraData").finish(),
64 }
65 }
66}
67
68impl fmt::Display for DeserializeError {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 match &self.0 {
71 DeserializeErrorInner::Postcard(inner) => inner.fmt(f),
72 DeserializeErrorInner::ExtraData => "extra data at the end".fmt(f),
73 }
74 }
75}
76
77impl Error for DeserializeError {}
78
79pub trait SerializedSize {
83 const SIZE: usize;
85}
86pub trait SerializedMaxSize {
90 const MAX_SIZE: usize;
92}
93
94pub trait SerializedFixedSize {
96 const FIXED_SIZE: usize;
98}
99
100impl<T: SerializedSize> SerializedMaxSize for T {
101 const MAX_SIZE: usize = T::SIZE;
102}
103
104#[rustfmt::skip]
105#[allow(unused_qualifications)] #[allow(clippy::manual_div_ceil)] mod integer_impls {
108 use super::SerializedFixedSize;
109 use super::SerializedMaxSize;
110 use super::SerializedSize;
111 use std::mem;
112
113 impl SerializedSize for bool { const SIZE: usize = 1; }
114
115 impl SerializedSize for i8 { const SIZE: usize = 1; }
116 impl SerializedSize for u8 { const SIZE: usize = 1; }
117
118 impl SerializedMaxSize for i16 { const MAX_SIZE: usize = (16 + 6) / 7; }
119 impl SerializedMaxSize for u16 { const MAX_SIZE: usize = (16 + 6) / 7; }
120 impl SerializedMaxSize for i32 { const MAX_SIZE: usize = (32 + 6) / 7; }
121 impl SerializedMaxSize for u32 { const MAX_SIZE: usize = (32 + 6) / 7; }
122 impl SerializedMaxSize for i64 { const MAX_SIZE: usize = (64 + 6) / 7; }
123 impl SerializedMaxSize for u64 { const MAX_SIZE: usize = (64 + 6) / 7; }
124
125 impl SerializedFixedSize for i16 { const FIXED_SIZE: usize = mem::size_of::<Self>(); }
126 impl SerializedFixedSize for u16 { const FIXED_SIZE: usize = mem::size_of::<Self>(); }
127 impl SerializedFixedSize for i32 { const FIXED_SIZE: usize = mem::size_of::<Self>(); }
128 impl SerializedFixedSize for u32 { const FIXED_SIZE: usize = mem::size_of::<Self>(); }
129 impl SerializedFixedSize for i64 { const FIXED_SIZE: usize = mem::size_of::<Self>(); }
130 impl SerializedFixedSize for u64 { const FIXED_SIZE: usize = mem::size_of::<Self>(); }
131}
132
133impl<T: SerializedMaxSize> SerializedMaxSize for Option<T> {
134 const MAX_SIZE: usize = option_max_size(T::MAX_SIZE);
135}
136
137impl<T: SerializedMaxSize, E: SerializedMaxSize> SerializedMaxSize for Result<T, E> {
138 const MAX_SIZE: usize = 1 + max(T::MAX_SIZE, E::MAX_SIZE);
139}
140
141impl<T: SerializedMaxSize> SerializedMaxSize for ops::Range<T> {
142 const MAX_SIZE: usize = 2 * T::MAX_SIZE;
143}
144
145impl<const NUM: usize, T: SerializedMaxSize> SerializedMaxSize for [T; NUM] {
146 const MAX_SIZE: usize = NUM * T::MAX_SIZE;
147}
148
149pub trait SerializeSeqMaxSize {
150 type Element;
151}
152
153impl<T> SerializeSeqMaxSize for Vec<T> {
154 type Element = T;
155}
156
157pub const fn uint_max_size(max_value: u64) -> usize {
159 let bits = match max_value.checked_ilog2() {
160 Some(n) => n + 1,
161 None => 1,
162 };
163 bits.div_ceil(7) as usize
164}
165
166pub const fn option_max_size(inner_size: usize) -> usize {
170 1 + inner_size
171}
172
173pub const fn seq_max_size(inner_size: usize, max_elems: usize) -> usize {
178 uint_max_size(max_elems as u64) + inner_size * max_elems
179}
180
181pub const fn max(a: usize, b: usize) -> usize {
182 if a >= b {
183 a
184 } else {
185 b
186 }
187}
188
189pub trait HexArray<'de>: Sized {
201 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
202 where
203 S: Serializer;
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: Deserializer<'de>;
207}
208
209impl<'de, const N: usize> HexArray<'de> for [u8; N] {
210 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
211 where
212 S: Serializer,
213 {
214 if serializer.is_human_readable() {
215 serializer.serialize_str(&hex::encode(self))
216 } else {
217 serde::Serialize::serialize(&FixedSizeByteArray::from(*self), serializer)
218 }
219 }
220
221 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
222 where
223 D: Deserializer<'de>,
224 {
225 use serde::Deserialize as _;
226 if deserializer.is_human_readable() {
227 let mut out = [0u8; N];
228 hex::decode_to_slice(String::deserialize(deserializer)?, &mut out)
229 .map_err(|_| D::Error::custom("Couldn't decode hex string"))?;
230 Ok(out)
231 } else {
232 Ok(
233 <FixedSizeByteArray<N> as serde::Deserialize>::deserialize(deserializer)?
234 .into_inner(),
235 )
236 }
237 }
238}
239
240pub trait Serialize: serde::Serialize {
241 fn serialize_to_writer<W: Write>(&self, writer: &mut W) -> io::Result<usize> {
242 struct Wrapper<'a, 'b, W: Write> {
243 inner: &'a mut W,
244 written: &'b mut usize,
245 error: &'b mut Option<io::Error>,
246 }
247 impl<W: Write> postcard::ser_flavors::Flavor for Wrapper<'_, '_, W> {
248 type Output = ();
249 fn try_push(&mut self, data: u8) -> postcard::Result<()> {
250 self.try_extend(&[data])
251 }
252 fn try_extend(&mut self, data: &[u8]) -> postcard::Result<()> {
253 assert!(self.error.is_none());
254 *self.written += data.len();
255 match self.inner.write_all(data) {
256 Ok(()) => Ok(()),
257 Err(e) => {
258 *self.error = Some(e);
259 Err(postcard::Error::SerializeBufferFull)
260 }
261 }
262 }
263 fn finalize(self) -> postcard::Result<()> {
264 Ok(())
265 }
266 }
267 let mut written = 0;
268 let mut error = None;
269 let wrapper = Wrapper {
270 inner: writer,
271 written: &mut written,
272 error: &mut error,
273 };
274 match postcard::serialize_with_flavor(self, wrapper) {
275 Ok(()) => Ok(written),
276 Err(e) => Err(io::Error::other(e)),
277 }
278 }
279 fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<usize> {
280 self.serialize_to_writer(writer)
281 }
282 fn serialize_to_vec(&self) -> Vec<u8> {
283 postcard::to_allocvec(self).unwrap()
284 }
285 fn serialized_size(&self) -> usize {
286 let size = postcard::ser_flavors::Size::default();
287 postcard::serialize_with_flavor(self, size).unwrap()
288 }
289}
290
291pub trait Deserialize: serde::de::DeserializeOwned {
292 fn deserialize_from_vec(bytes: &[u8]) -> Result<Self, DeserializeError> {
294 postcard::from_bytes(bytes).map_err(DeserializeError::from)
295 }
296 fn deserialize_take(bytes: &[u8]) -> Result<(Self, &[u8]), DeserializeError> {
298 postcard::take_from_bytes(bytes).map_err(DeserializeError::from)
299 }
300 fn deserialize_all(bytes: &[u8]) -> Result<Self, DeserializeError> {
302 let (result, rest) = Self::deserialize_take(bytes)?;
303 if !rest.is_empty() {
304 return Err(DeserializeError::extra_data());
305 }
306 Ok(result)
307 }
308}
309
310impl<T: serde::Serialize> Serialize for T {}
311
312impl<T: serde::de::DeserializeOwned> Deserialize for T {}
313
314#[cfg(test)]
315mod test {
316 use super::{Deserialize, DeserializeError};
317
318 #[test]
319 fn deserialize_all() {
320 let bytes = b"\x12\x34";
321 assert_eq!(u8::deserialize_from_vec(bytes), Ok(0x12));
322 assert_eq!(u8::deserialize_take(bytes), Ok((0x12, &b"\x34"[..])));
323 assert_eq!(
324 u8::deserialize_all(bytes),
325 Err(DeserializeError::extra_data()),
326 );
327 }
328}