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