• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 #![cfg_attr(not(feature = "std"), no_std)]
6 extern crate alloc;
7 
8 use alloc::boxed::Box;
9 
10 pub use alloc::vec::Vec;
11 
12 mod array;
13 
14 /// Optimized encoding and decoding for types that can be represented by `Vec<u8>`.
15 ///
16 /// Compatible with derive macros by using `mls_codec(with = "mls_rs_codec::byte_vec")`
17 pub mod byte_vec;
18 
19 pub mod iter;
20 
21 mod bool;
22 mod cow;
23 mod map;
24 mod option;
25 mod stdint;
26 mod string;
27 mod tuple;
28 mod varint;
29 mod vec;
30 
31 pub use varint::*;
32 
33 pub use mls_rs_codec_derive::*;
34 
35 #[derive(Debug)]
36 #[cfg_attr(feature = "std", derive(thiserror::Error))]
37 #[non_exhaustive]
38 pub enum Error {
39     #[cfg_attr(feature = "std", error("Integer out of range for VarInt"))]
40     VarIntOutOfRange,
41     #[cfg_attr(feature = "std", error("Invalid varint prefix {0}"))]
42     InvalidVarIntPrefix(u8),
43     #[cfg_attr(feature = "std", error("VarInt does not use the min-length encoding"))]
44     VarIntMinimumLengthEncoding,
45     #[cfg_attr(feature = "std", error("UnexpectedEOF"))]
46     UnexpectedEOF,
47     #[cfg_attr(feature = "std", error("Option marker out of range: {0}"))]
48     OptionOutOfRange(u8),
49     #[cfg_attr(feature = "std", error("Unsupported enum discriminant"))]
50     UnsupportedEnumDiscriminant,
51     #[cfg_attr(feature = "std", error("Expected UTF-8 string"))]
52     Utf8,
53     #[cfg_attr(feature = "std", error("mls codec error: {0}"))]
54     Custom(u8),
55 }
56 
57 /// Trait that determines the encoded length in MLS encoding.
58 pub trait MlsSize {
mls_encoded_len(&self) -> usize59     fn mls_encoded_len(&self) -> usize;
60 }
61 
62 impl<T> MlsSize for &T
63 where
64     T: MlsSize + ?Sized,
65 {
66     #[inline]
mls_encoded_len(&self) -> usize67     fn mls_encoded_len(&self) -> usize {
68         (*self).mls_encoded_len()
69     }
70 }
71 
72 impl<T> MlsSize for Box<T>
73 where
74     T: MlsSize + ?Sized,
75 {
76     #[inline]
mls_encoded_len(&self) -> usize77     fn mls_encoded_len(&self) -> usize {
78         self.as_ref().mls_encoded_len()
79     }
80 }
81 
82 /// Trait to support serializing a type with MLS encoding.
83 pub trait MlsEncode: MlsSize {
mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error>84     fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error>;
85 
86     #[inline]
mls_encode_to_vec(&self) -> Result<Vec<u8>, Error>87     fn mls_encode_to_vec(&self) -> Result<Vec<u8>, Error> {
88         #[cfg(feature = "preallocate")]
89         let mut vec = Vec::with_capacity(self.mls_encoded_len());
90 
91         #[cfg(not(feature = "preallocate"))]
92         let mut vec = Vec::new();
93 
94         self.mls_encode(&mut vec)?;
95 
96         Ok(vec)
97     }
98 }
99 
100 impl<T> MlsEncode for &T
101 where
102     T: MlsEncode + ?Sized,
103 {
104     #[inline]
mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error>105     fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
106         (*self).mls_encode(writer)
107     }
108 }
109 
110 impl<T> MlsEncode for Box<T>
111 where
112     T: MlsEncode + ?Sized,
113 {
114     #[inline]
mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error>115     fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
116         self.as_ref().mls_encode(writer)
117     }
118 }
119 
120 /// Trait to support deserialzing to a type using MLS encoding.
121 pub trait MlsDecode: Sized {
mls_decode(reader: &mut &[u8]) -> Result<Self, Error>122     fn mls_decode(reader: &mut &[u8]) -> Result<Self, Error>;
123 }
124 
125 impl<T: MlsDecode> MlsDecode for Box<T> {
126     #[inline]
mls_decode(reader: &mut &[u8]) -> Result<Self, Error>127     fn mls_decode(reader: &mut &[u8]) -> Result<Self, Error> {
128         T::mls_decode(reader).map(Box::new)
129     }
130 }
131