blob: 7db6f86051cccbd44879849e6079596ac321a29f [file] [log] [blame]
// 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)
}
}