summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..7db6f86
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,132 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// Copyright by contributors to this project.
+// SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+#![cfg_attr(not(feature = "std"), no_std)]
+extern crate alloc;
+
+use alloc::boxed::Box;
+
+pub use alloc::vec::Vec;
+
+mod array;
+
+/// Optimized encoding and decoding for types that can be represented by `Vec<u8>`.
+///
+/// Compatible with derive macros by using `mls_codec(with = "mls_rs_codec::byte_vec")`
+pub mod byte_vec;
+
+pub mod iter;
+
+mod cow;
+mod map;
+mod option;
+mod stdint;
+mod string;
+mod tuple;
+mod varint;
+mod vec;
+
+pub use varint::*;
+
+pub use mls_rs_codec_derive::*;
+
+#[derive(Debug)]
+#[cfg_attr(feature = "std", derive(thiserror::Error))]
+#[non_exhaustive]
+pub enum Error {
+ #[cfg_attr(feature = "std", error("Integer out of range for VarInt"))]
+ VarIntOutOfRange,
+ #[cfg_attr(feature = "std", error("Invalid varint prefix {0}"))]
+ InvalidVarIntPrefix(u8),
+ #[cfg_attr(feature = "std", error("VarInt does not use the min-length encoding"))]
+ VarIntMinimumLengthEncoding,
+ #[cfg_attr(feature = "std", error("UnexpectedEOF"))]
+ UnexpectedEOF,
+ #[cfg_attr(feature = "std", error("Option marker out of range: {0}"))]
+ OptionOutOfRange(u8),
+ #[cfg_attr(feature = "std", error("Unsupported enum discriminant"))]
+ UnsupportedEnumDiscriminant,
+ #[cfg_attr(feature = "std", error("Expected UTF-8 string"))]
+ Utf8,
+ #[cfg_attr(feature = "std", error("mls codec error: {0}"))]
+ Custom(u8),
+}
+
+/// Trait that determines the encoded length in MLS encoding.
+pub trait MlsSize {
+ fn mls_encoded_len(&self) -> usize;
+}
+
+impl<T> MlsSize for &T
+where
+ T: MlsSize + ?Sized,
+{
+ #[inline]
+ fn mls_encoded_len(&self) -> usize {
+ (*self).mls_encoded_len()
+ }
+}
+
+impl<T> MlsSize for Box<T>
+where
+ T: MlsSize + ?Sized,
+{
+ #[inline]
+ fn mls_encoded_len(&self) -> usize {
+ self.as_ref().mls_encoded_len()
+ }
+}
+
+/// Trait to support serializing a type with MLS encoding.
+pub trait MlsEncode: MlsSize {
+ fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error>;
+
+ #[inline]
+ fn mls_encode_to_vec(&self) -> Result<Vec<u8>, Error> {
+ #[cfg(feature = "preallocate")]
+ let mut vec = Vec::with_capacity(self.mls_encoded_len());
+
+ #[cfg(not(feature = "preallocate"))]
+ let mut vec = Vec::new();
+
+ self.mls_encode(&mut vec)?;
+
+ Ok(vec)
+ }
+}
+
+impl<T> MlsEncode for &T
+where
+ T: MlsEncode + ?Sized,
+{
+ #[inline]
+ fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
+ (*self).mls_encode(writer)
+ }
+}
+
+impl<T> MlsEncode for Box<T>
+where
+ T: MlsEncode + ?Sized,
+{
+ #[inline]
+ fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
+ self.as_ref().mls_encode(writer)
+ }
+}
+
+/// Trait to support deserialzing to a type using MLS encoding.
+pub trait MlsDecode: Sized {
+ fn mls_decode(reader: &mut &[u8]) -> Result<Self, Error>;
+}
+
+impl<T> MlsDecode for Box<T>
+where
+ T: MlsDecode + ?Sized,
+{
+ #[inline]
+ fn mls_decode(reader: &mut &[u8]) -> Result<Self, Error> {
+ T::mls_decode(reader).map(Box::new)
+ }
+}