1#[cfg(feature = "serde")]
2pub mod serde;
3
4use crate::marker::Marker;
5
6use byteorder::{BigEndian, ByteOrder};
7#[allow(unused_imports)]
8use core::convert::TryFrom;
9use core::{convert::From, ops::Deref};
10use num_traits::cast::FromPrimitive;
11
12#[derive(Debug)]
14pub enum Error {
15 EndOfBuffer,
17 OutOfBounds,
19 InvalidType,
21}
22
23impl ::core::fmt::Display for Error {
24 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
25 match self {
26 Error::OutOfBounds => f.write_str("Out of bounds"),
27 Error::InvalidType => f.write_str("Invalid type"),
28 Error::EndOfBuffer => f.write_str("End of buffer"),
29 }
30 }
31}
32
33#[cfg(feature = "std")]
34impl ::std::error::Error for Error {}
35
36pub trait SerializeIntoSlice {
37 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error>;
38}
39
40pub fn serialize_u8(value: u8, buf: &mut [u8]) -> Result<usize, Error> {
41 if value < 0x80 {
42 if buf.is_empty() {
43 return Err(Error::EndOfBuffer);
44 }
45 buf[0] = value;
46 Ok(1)
47 } else {
48 if buf.len() < 2 {
49 return Err(Error::EndOfBuffer);
50 }
51 buf[0] = Marker::U8.to_u8();
52 buf[1] = value;
53 Ok(2)
54 }
55}
56pub fn serialize_u16(value: u16, buf: &mut [u8]) -> Result<usize, Error> {
57 if let Ok(value) = u8::try_from(value) {
58 serialize_u8(value, buf)
59 } else {
60 if buf.len() < 3 {
61 return Err(Error::EndOfBuffer);
62 }
63 buf[0] = Marker::U16.to_u8();
64 BigEndian::write_u16(&mut buf[1..], value);
65 Ok(3)
66 }
67}
68pub fn serialize_u32(value: u32, buf: &mut [u8]) -> Result<usize, Error> {
69 if let Ok(value) = u16::try_from(value) {
70 serialize_u16(value, buf)
71 } else {
72 if buf.len() < 5 {
73 return Err(Error::EndOfBuffer);
74 }
75 buf[0] = Marker::U32.to_u8();
76 BigEndian::write_u32(&mut buf[1..], value);
77 Ok(5)
78 }
79}
80#[cfg(feature = "u64")]
81pub fn serialize_u64(value: u64, buf: &mut [u8]) -> Result<usize, Error> {
82 if let Ok(value) = u32::try_from(value) {
83 serialize_u32(value, buf)
84 } else {
85 if buf.len() < 9 {
86 return Err(Error::EndOfBuffer);
87 }
88 buf[0] = Marker::U64.to_u8();
89 BigEndian::write_u64(&mut buf[1..], value);
90 Ok(9)
91 }
92}
93#[allow(clippy::single_match_else)]
94pub fn serialize_i8(value: i8, buf: &mut [u8]) -> Result<usize, Error> {
95 match value {
96 -32..=0x7f => {
97 if buf.is_empty() {
98 return Err(Error::EndOfBuffer);
99 }
100 buf[0] = value as u8;
101 Ok(1)
102 }
103 _ => {
104 if buf.len() < 2 {
105 return Err(Error::EndOfBuffer);
106 }
107 buf[0] = Marker::I8.to_u8();
108 buf[1] = value as u8;
109 Ok(2)
110 }
111 }
112}
113pub fn serialize_i16(value: i16, buf: &mut [u8]) -> Result<usize, Error> {
114 if let Some(value) = u16::from_i16(value) {
116 serialize_u16(value, buf)
117 } else if let Some(value) = i8::from_i16(value) {
118 serialize_i8(value, buf)
119 } else {
120 if buf.len() < 3 {
121 return Err(Error::EndOfBuffer);
122 }
123 buf[0] = Marker::I16.to_u8();
124 BigEndian::write_i16(&mut buf[1..], value);
125 Ok(3)
126 }
127}
128pub fn serialize_i32(value: i32, buf: &mut [u8]) -> Result<usize, Error> {
129 if let Some(value) = u32::from_i32(value) {
131 serialize_u32(value, buf)
132 } else if let Some(value) = i16::from_i32(value) {
133 serialize_i16(value, buf)
134 } else {
135 if buf.len() < 5 {
136 return Err(Error::EndOfBuffer);
137 }
138 buf[0] = Marker::I32.to_u8();
139 BigEndian::write_i32(&mut buf[1..], value);
140 Ok(5)
141 }
142}
143#[cfg(feature = "i64")]
144pub fn serialize_i64(value: i64, buf: &mut [u8]) -> Result<usize, Error> {
145 #[cfg(feature = "u64")]
146 if let Some(value) = u64::from_i64(value) {
147 return serialize_u64(value, buf);
148 }
149 if let Some(value) = i32::from_i64(value) {
150 serialize_i32(value, buf)
151 } else {
152 if buf.len() < 9 {
153 return Err(Error::EndOfBuffer);
154 }
155 buf[0] = Marker::I64.to_u8();
156 BigEndian::write_i64(&mut buf[1..], value);
157 Ok(9)
158 }
159}
160pub fn serialize_f32(value: f32, buf: &mut [u8]) -> Result<usize, Error> {
161 if buf.len() < 5 {
162 return Err(Error::EndOfBuffer);
163 }
164 buf[0] = Marker::F32.to_u8();
165 BigEndian::write_f32(&mut buf[1..], value);
166 Ok(5)
167}
168pub fn serialize_f64(value: f64, buf: &mut [u8]) -> Result<usize, Error> {
169 if buf.len() < 9 {
170 return Err(Error::EndOfBuffer);
171 }
172 buf[0] = Marker::F64.to_u8();
173 BigEndian::write_f64(&mut buf[1..], value);
174 Ok(9)
175}
176
177impl SerializeIntoSlice for u8 {
178 #[inline(always)]
179 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_u8(*self, buf) }
180}
181impl SerializeIntoSlice for u16 {
182 #[inline(always)]
183 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_u16(*self, buf) }
184}
185impl SerializeIntoSlice for u32 {
186 #[inline(always)]
187 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_u32(*self, buf) }
188}
189#[cfg(feature = "u64")]
190impl SerializeIntoSlice for u64 {
191 #[inline(always)]
192 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_u64(*self, buf) }
193}
194impl SerializeIntoSlice for i8 {
195 #[inline(always)]
196 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_i8(*self, buf) }
197}
198impl SerializeIntoSlice for i16 {
199 #[inline(always)]
200 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_i16(*self, buf) }
201}
202impl SerializeIntoSlice for i32 {
203 #[inline(always)]
204 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_i32(*self, buf) }
205}
206#[cfg(feature = "i64")]
207impl SerializeIntoSlice for i64 {
208 #[inline(always)]
209 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_i64(*self, buf) }
210}
211
212impl SerializeIntoSlice for f32 {
213 #[inline(always)]
214 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_f32(*self, buf) }
215}
216impl SerializeIntoSlice for f64 {
217 #[inline(always)]
218 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_f64(*self, buf) }
219}
220
221impl SerializeIntoSlice for bool {
222 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
223 if buf.is_empty() {
224 return Err(Error::EndOfBuffer);
225 }
226 buf[0] = if *self { Marker::True.to_u8() } else { Marker::False.to_u8() };
227 Ok(1)
228 }
229}
230
231impl<T> SerializeIntoSlice for Option<T>
232where T: SerializeIntoSlice
233{
234 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
235 if let Some(value) = self {
236 SerializeIntoSlice::write_into_slice(value, buf)
237 } else {
238 if buf.is_empty() {
239 return Err(Error::EndOfBuffer);
240 }
241 buf[0] = Marker::Null.to_u8();
242 Ok(1)
243 }
244 }
245}
246impl SerializeIntoSlice for () {
247 #[inline(always)]
248 fn write_into_slice(&self, _buf: &mut [u8]) -> Result<usize, Error> { Ok(0) }
249}
250
251#[cfg(any(feature = "alloc", feature = "std"))]
252extern crate alloc;
253#[cfg(any(feature = "alloc", feature = "std"))]
254use alloc::borrow::Cow;
255
256#[derive(PartialEq, Eq)]
257#[cfg_attr(any(test, feature = "derive-debug"), derive(core::fmt::Debug))]
258#[repr(transparent)]
259pub struct Binary<'a>(
260 #[cfg(not(any(feature = "alloc", feature = "std")))] &'a [u8],
261 #[cfg(any(feature = "alloc", feature = "std"))] Cow<'a, [u8]>,
262);
263
264impl<'a> Binary<'a> {
265 #[cfg(not(any(feature = "alloc", feature = "std")))]
266 #[inline]
267 pub const fn new(slice: &'a [u8]) -> Self { Binary(slice) }
268 #[cfg(any(feature = "alloc", feature = "std"))]
269 #[inline]
270 pub const fn new(slice: &'a [u8]) -> Self { Binary(Cow::Borrowed(slice)) }
271}
272
273impl<'a> Deref for Binary<'a> {
274 type Target = [u8];
275 #[cfg(not(any(feature = "alloc", feature = "std")))]
276 #[inline]
277 fn deref(&self) -> &Self::Target { &self.0 }
278 #[cfg(any(feature = "alloc", feature = "std"))]
279 #[inline]
280 fn deref(&self) -> &Self::Target { &self.0 }
281}
282impl<'a> From<&'a [u8]> for Binary<'a> {
283 #[inline]
284 fn from(slice: &'a [u8]) -> Self { Binary::new(slice) }
285}
286
287#[cfg(feature = "serde")]
288impl<'a> ::serde::Serialize for Binary<'a> {
289 fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { serializer.serialize_bytes(&self) }
290}
291#[cfg(feature = "serde")]
292struct BinaryVisitor;
293
294#[cfg(feature = "serde")]
295impl<'de> ::serde::de::Visitor<'de> for BinaryVisitor {
296 type Value = Binary<'de>;
297 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str("a byte array") }
298 fn visit_borrowed_bytes<E: ::serde::de::Error>(self, v: &'de [u8]) -> Result<Self::Value, E> { Ok(Binary::new(v)) }
299 #[cfg(any(feature = "alloc", feature = "std"))]
300 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
301 where A: ::serde::de::SeqAccess<'de> {
302 extern crate alloc;
303 #[cfg(not(feature = "std"))]
304 use alloc::vec::Vec;
305 let mut data = if let Some(len) = seq.size_hint() {
306 Vec::with_capacity(len)
307 } else {
308 Vec::new()
309 };
310 while let Some(e) = seq.next_element::<u8>()? {
311 data.push(e);
312 }
313 Ok(Binary(Cow::Owned(data)))
314 }
315}
316#[cfg(feature = "serde")]
317impl<'a> ::serde::Deserialize<'a> for Binary<'a> {
318 fn deserialize<D: ::serde::Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error> {
319 deserializer.deserialize_bytes(BinaryVisitor)
320 }
321}
322
323impl<'a> SerializeIntoSlice for Binary<'a> {
330 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
331 let n = self.len();
332 if let Ok(n8) = u8::try_from(n) {
333 if buf.len() < 2 + n {
334 return Err(Error::EndOfBuffer);
335 }
336 buf[0] = Marker::Bin8.to_u8();
337 buf[1] = n8;
338 buf[2..(2 + n)].clone_from_slice(self);
339 return Ok(2 + n);
340 }
341 #[cfg(feature = "bin16")]
342 if let Ok(n16) = u16::try_from(n) {
343 if buf.len() < 3 + n {
344 return Err(Error::EndOfBuffer);
345 }
346 buf[0] = Marker::Bin16.to_u8();
347 BigEndian::write_u16(&mut buf[1..], n16);
348 buf[3..(3 + n)].clone_from_slice(self);
349 return Ok(3 + n);
350 }
351 #[cfg(feature = "bin32")]
352 if let Ok(n32) = u32::try_from(n) {
353 if buf.len() < 5 + n {
354 return Err(Error::EndOfBuffer);
355 }
356 buf[0] = Marker::Bin32.to_u8();
357 BigEndian::write_u32(&mut buf[1..], n32);
358 buf[5..(5 + n)].clone_from_slice(self);
359 return Ok(5 + n);
360 }
361 unimplemented!()
362 }
363}
364
365impl<K, V> SerializeIntoSlice for &(K, V)
366where
367 K: SerializeIntoSlice,
368 V: SerializeIntoSlice,
369{
370 #[inline(always)]
371 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
372 let index = serialize_map_kay_value(&self.0, &self.1, buf)?;
373 Ok(index)
374 }
375}
376
377impl SerializeIntoSlice for &str {
384 #[allow(clippy::cast_possible_truncation)]
385 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
386 let n = self.len();
387 match n {
388 0..=0x1f => {
390 let header_len = 1;
391 if buf.len() < header_len + n {
392 return Err(Error::EndOfBuffer);
393 }
394 buf[0] = Marker::FixStr(n as u8).to_u8();
395 buf[header_len..(header_len + n)].clone_from_slice(self.as_bytes());
396 Ok(header_len + n)
397 }
398 0x20..=0xff => {
399 let header_len = 2;
400 if buf.len() < header_len + n {
401 return Err(Error::EndOfBuffer);
402 }
403 buf[0] = Marker::Str8.to_u8();
404 buf[1] = n as u8;
405 buf[header_len..(header_len + n)].clone_from_slice(self.as_bytes());
406 Ok(header_len + n)
407 }
408 _ => {
409 #[cfg(feature = "str16")]
410 if let Ok(n16) = u16::try_from(n) {
411 let header_len = 3;
412 if buf.len() < header_len + n {
413 return Err(Error::EndOfBuffer);
414 }
415 buf[0] = Marker::Str16.to_u8();
416 BigEndian::write_u16(&mut buf[1..], n16);
417 buf[header_len..(header_len + n)].clone_from_slice(self.as_bytes());
418 return Ok(header_len + n);
419 }
420 #[cfg(feature = "str32")]
421 if let Ok(n32) = u32::try_from(n) {
422 let header_len = 5;
423 if buf.len() < header_len + n {
424 return Err(Error::EndOfBuffer);
425 }
426 buf[0] = Marker::Str32.to_u8();
427 BigEndian::write_u32(&mut buf[1..], n32);
428 buf[header_len..(header_len + n)].clone_from_slice(self.as_bytes());
429 return Ok(header_len + n);
430 }
431 unimplemented!()
432 }
433 }
434 }
435}
436
437impl<K, V> SerializeIntoSlice for &[(K, V)]
438where
439 K: SerializeIntoSlice,
440 V: SerializeIntoSlice,
441{
442 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
443 let mut index = serialize_map_start(self.len(), buf)?;
445 for kv in self.iter() {
446 index += kv.write_into_slice(&mut buf[index..])?;
447 }
448 Ok(index)
449 }
450}
451
452impl<T> SerializeIntoSlice for &[T]
453where T: SerializeIntoSlice
454{
455 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> {
456 let mut index = serialize_array_start(self.len(), buf)?;
458 for i in self.iter() {
459 index += SerializeIntoSlice::write_into_slice(i, &mut buf[index..])?;
460 }
461 Ok(index)
462 }
463}
464
465#[derive(Copy, Clone)]
466pub enum SequenceType {
467 Array,
468 Map,
469}
470impl SequenceType {
471 pub fn serialize_start(self, n: usize, buf: &mut [u8]) -> Result<usize, Error> {
472 match self {
473 SequenceType::Array => serialize_array_start(n, buf),
474 SequenceType::Map => serialize_map_start(n, buf),
475 }
476 }
477}
478
479pub fn serialize_sequence<T: SerializeIntoSlice>(seq: &[T], typ: SequenceType, buf: &mut [u8]) -> Result<usize, Error> {
480 let mut index = typ.serialize_start(seq.len(), buf)?;
481 for i in seq.iter() {
482 index += SerializeIntoSlice::write_into_slice(i, &mut buf[index..])?;
483 }
484 Ok(index)
485}
486
487#[allow(clippy::cast_possible_truncation)]
494pub fn serialize_array_start(n: usize, buf: &mut [u8]) -> Result<usize, Error> {
495 if n <= crate::marker::FIXARRAY_SIZE as usize {
496 if buf.len() < 1 + n {
497 return Err(Error::EndOfBuffer);
498 }
499 buf[0] = Marker::FixArray(n as u8).to_u8();
500 Ok(1)
501 } else {
502 #[cfg(feature = "array16")]
503 if let Ok(n) = u16::try_from(n) {
504 buf[0] = Marker::Array16.to_u8();
505 BigEndian::write_u16(&mut buf[1..], n);
506 return Ok(3);
507 }
508 #[cfg(feature = "array32")]
509 if let Ok(n) = u32::try_from(n) {
510 buf[0] = Marker::Array32.to_u8();
511 BigEndian::write_u32(&mut buf[1..], n);
512 return Ok(5);
513 }
514 unimplemented!()
515 }
516}
517
518#[allow(clippy::cast_possible_truncation)]
525pub fn serialize_map_start(n: usize, buf: &mut [u8]) -> Result<usize, Error> {
526 if n <= crate::marker::FIXMAP_SIZE as usize {
527 if buf.len() < 1 + n {
528 return Err(Error::EndOfBuffer);
529 }
530 buf[0] = Marker::FixMap(n as u8).to_u8();
531 Ok(1)
532 } else {
533 #[cfg(feature = "map16")]
534 if let Ok(n) = u16::try_from(n) {
535 buf[0] = Marker::Map16.to_u8();
536 BigEndian::write_u16(&mut buf[1..], n);
537 return Ok(3);
538 }
539 #[cfg(feature = "map32")]
540 if let Ok(n) = u32::try_from(n) {
541 buf[0] = Marker::Map32.to_u8();
542 BigEndian::write_u32(&mut buf[1..], n);
543 return Ok(5);
544 }
545 unimplemented!()
546 }
547}
548pub fn serialize_map_kay_value<K: SerializeIntoSlice, V: SerializeIntoSlice>(key: &K, value: &V, buf: &mut [u8]) -> Result<usize, Error> {
549 let mut index = 0;
550 index += SerializeIntoSlice::write_into_slice(key, &mut buf[index..])?;
551 index += SerializeIntoSlice::write_into_slice(value, &mut buf[index..])?;
552 Ok(index)
553}