#![cfg_attr(feature = "future_deprecations", allow(deprecated))]
use super::alloc::vec::Vec;
use core::fmt;
#[cfg(feature = "std")]
use zeroize::{Zeroize, ZeroizeOnDrop};
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
#[cfg(feature = "serde")]
use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
use crate::{DeserializeBytes, Error, SerializeBytes, Size};
#[cfg(feature = "mls")]
const MAX_MLS_LEN: u64 = (1 << 30) - 1;
struct ContentLength(super::TlsVarInt);
impl ContentLength {
#[cfg(all(not(feature = "mls"), feature = "arbitrary"))]
const MAX: u64 = crate::TlsVarInt::MAX;
#[cfg(feature = "mls")]
const MAX: u64 = MAX_MLS_LEN;
fn new(value: super::TlsVarInt) -> Result<Self, Error> {
#[cfg(feature = "mls")]
if Self::MAX < value.value() {
return Err(Error::InvalidVectorLength);
}
Ok(Self(value))
}
fn from_usize(value: usize) -> Result<Self, Error> {
Self::new(super::TlsVarInt::try_new(value.try_into()?)?)
}
}
impl Size for ContentLength {
fn tls_serialized_len(&self) -> usize {
self.0.tls_serialized_len()
}
}
impl DeserializeBytes for ContentLength {
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
let (value, remainder) = super::TlsVarInt::tls_deserialize_bytes(bytes)?;
Ok((Self(value), remainder))
}
}
impl<T: Size> Size for Vec<T> {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
self.as_slice().tls_serialized_len()
}
}
impl<T: Size> Size for &Vec<T> {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
(*self).tls_serialized_len()
}
}
impl<T: DeserializeBytes> DeserializeBytes for Vec<T> {
#[inline(always)]
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
let (length, mut remainder) = ContentLength::tls_deserialize_bytes(bytes)?;
let length: usize = length.0.value().try_into()?;
if length == 0 {
return Ok((Vec::new(), remainder));
}
let mut result = Vec::new();
let mut read = 0usize;
while read < length {
let (element, next_remainder) = T::tls_deserialize_bytes(remainder)?;
let consumed = remainder.len() - next_remainder.len();
remainder = next_remainder;
result.push(element);
if consumed == 0 {
return Err(Error::DecodingError(
"Vector element consumed 0 bytes; refusing to loop".into(),
));
}
read += consumed;
}
if read != length {
return Err(Error::DecodingError(format!(
"Vector length mismatch: declared {length} bytes but elements consumed {read}"
)));
}
Ok((result, remainder))
}
}
impl SerializeBytes for VLBytes {
#[inline(always)]
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
let content_length = self.as_slice().len();
let length = ContentLength::from_usize(content_length)?;
let len_len = length.0.bytes_len();
let mut out = Vec::with_capacity(crate::checked_alloc_len(content_length, len_len)?);
out.resize(len_len, 0);
length.0.write_bytes(&mut out)?;
out.extend(self.as_slice());
#[cfg(debug_assertions)]
if out.len() - len_len != content_length {
return Err(Error::LibraryError);
}
Ok(out)
}
}
impl SerializeBytes for &VLBytes {
#[inline(always)]
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
(*self).tls_serialize_bytes()
}
}
impl<T: SerializeBytes> SerializeBytes for &[T] {
#[inline(always)]
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
let content_length = self.iter().try_fold(0usize, |acc, e| {
crate::checked_len_add(acc, e.tls_serialized_len())
})?;
let length = ContentLength::from_usize(content_length)?;
let len_len = length.0.bytes_len();
let mut out = Vec::with_capacity(crate::checked_alloc_len(content_length, len_len)?);
out.resize(len_len, 0);
length.0.write_bytes(&mut out)?;
for e in self.iter() {
out.append(&mut e.tls_serialize_bytes()?);
}
#[cfg(debug_assertions)]
if out.len() - len_len != content_length {
return Err(Error::LibraryError);
}
Ok(out)
}
}
impl<T: SerializeBytes> SerializeBytes for &Vec<T> {
#[inline(always)]
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
self.as_slice().tls_serialize_bytes()
}
}
impl<T: SerializeBytes> SerializeBytes for Vec<T> {
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
self.as_slice().tls_serialize_bytes()
}
}
impl<T: Size> Size for &[T] {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
let content_length = self
.iter()
.fold(0, |acc, e| crate::len_add(acc, e.tls_serialized_len()));
let len_len = ContentLength::from_usize(content_length)
.map(|content_length| content_length.0.bytes_len())
.unwrap_or({
0
});
crate::len_add(content_length, len_len)
}
}
fn write_hex(f: &mut fmt::Formatter<'_>, data: &[u8]) -> fmt::Result {
if !data.is_empty() {
write!(f, "0x")?;
for byte in data {
write!(f, "{byte:02x}")?;
}
} else {
write!(f, "b\"\"")?;
}
Ok(())
}
macro_rules! impl_vl_bytes_generic {
($name:ident) => {
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {{ ", stringify!($name))?;
write_hex(f, &self.vec())?;
write!(f, " }}")
}
}
impl $name {
pub fn as_slice(&self) -> &[u8] {
self.vec().as_ref()
}
#[inline]
pub fn push(&mut self, value: u8) {
self.vec_mut().push(value);
}
#[inline]
pub fn pop(&mut self) -> Option<u8> {
self.vec_mut().pop()
}
}
impl From<Vec<u8>> for $name {
fn from(vec: Vec<u8>) -> Self {
Self::new(vec)
}
}
impl From<&[u8]> for $name {
fn from(slice: &[u8]) -> Self {
Self::new(slice.to_vec())
}
}
impl<const N: usize> From<&[u8; N]> for $name {
fn from(slice: &[u8; N]) -> Self {
Self::new(slice.to_vec())
}
}
impl AsRef<[u8]> for $name {
fn as_ref(&self) -> &[u8] {
&self.vec()
}
}
};
}
#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[cfg_attr(
feature = "future_deprecations",
deprecated(
note = "Use `VLByteVec` instead. `VLBytes` does not produce a compact serde representation \
of byte vectors. The serde format of `VLByteVec` is not compatible with `VLBytes`."
)
)]
pub struct VLBytes {
vec: Vec<u8>,
}
impl VLBytes {
pub fn new(vec: Vec<u8>) -> Self {
Self { vec }
}
fn vec(&self) -> &[u8] {
&self.vec
}
fn vec_mut(&mut self) -> &mut Vec<u8> {
&mut self.vec
}
}
impl_vl_bytes_generic!(VLBytes);
#[cfg(feature = "std")]
impl Zeroize for VLBytes {
fn zeroize(&mut self) {
self.vec.zeroize();
}
}
impl From<VLBytes> for Vec<u8> {
fn from(b: VLBytes) -> Self {
b.vec
}
}
#[inline(always)]
fn tls_serialize_bytes_len(bytes: &[u8]) -> usize {
let content_length = bytes.len();
let len_len = ContentLength::from_usize(content_length)
.map(|content_length| content_length.0.bytes_len())
.unwrap_or({
0
});
content_length + len_len
}
impl Size for VLBytes {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
tls_serialize_bytes_len(self.as_slice())
}
}
impl DeserializeBytes for VLBytes {
#[inline(always)]
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
let (length, remainder) = ContentLength::tls_deserialize_bytes(bytes)?;
let length: usize = length.0.value().try_into()?;
if length == 0 {
return Ok((Self::new(vec![]), remainder));
}
match remainder.get(..length).ok_or(Error::EndOfStream) {
Ok(vec) => Ok((Self { vec: vec.to_vec() }, &remainder[length..])),
Err(_e) => {
let remaining_len = remainder.len();
if !cfg!(fuzzing) {
debug_assert_eq!(
remaining_len, length,
"Expected to read {length} bytes but {remaining_len} were read.",
);
}
Err(Error::DecodingError(format!(
"{remaining_len} bytes were read but {length} were expected",
)))
}
}
}
}
impl Size for &VLBytes {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
(*self).tls_serialized_len()
}
}
#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct VLByteVec {
#[cfg_attr(feature = "serde", serde(serialize_with = "serde_bytes::serialize"))]
#[cfg_attr(
feature = "serde",
serde(deserialize_with = "serde_compat::deserialize_vlbytes_compat")
)]
vec: Vec<u8>,
}
impl VLByteVec {
pub fn new(vec: Vec<u8>) -> Self {
Self { vec }
}
fn vec(&self) -> &[u8] {
&self.vec
}
fn vec_mut(&mut self) -> &mut Vec<u8> {
&mut self.vec
}
}
impl_vl_bytes_generic!(VLByteVec);
#[cfg(feature = "std")]
impl Zeroize for VLByteVec {
fn zeroize(&mut self) {
self.vec.zeroize();
}
}
impl From<VLByteVec> for Vec<u8> {
fn from(b: VLByteVec) -> Self {
b.vec
}
}
impl Size for VLByteVec {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
tls_serialize_bytes_len(self.as_slice())
}
}
impl DeserializeBytes for VLByteVec {
#[inline(always)]
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
let (length, remainder) = ContentLength::tls_deserialize_bytes(bytes)?;
let length: usize = length.0.value().try_into()?;
if length == 0 {
return Ok((Self::new(vec![]), remainder));
}
match remainder.get(..length).ok_or(Error::EndOfStream) {
Ok(vec) => Ok((Self { vec: vec.to_vec() }, &remainder[length..])),
Err(_e) => {
let remaining_len = remainder.len();
if !cfg!(fuzzing) {
debug_assert_eq!(
remaining_len, length,
"Expected to read {length} bytes but {remaining_len} were read.",
);
}
Err(Error::DecodingError(format!(
"{remaining_len} bytes were read but {length} were expected",
)))
}
}
}
}
impl Size for &VLByteVec {
#[inline(always)]
fn tls_serialized_len(&self) -> usize {
(*self).tls_serialized_len()
}
}
#[cfg(feature = "serde")]
mod serde_compat {
use super::Vec;
use crate::alloc::string::String;
use core::fmt;
use serde::{Deserializer, de};
pub(super) fn deserialize_vlbytes_compat<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
struct CompatVisitor;
impl<'de> de::Visitor<'de> for CompatVisitor {
type Value = Vec<u8>;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(
"a byte blob, a sequence of `u8`, or a struct with a `vec` field \
containing a sequence of `u8`",
)
}
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
Ok(v.to_vec())
}
fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
Ok(v)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let cap = core::cmp::min(seq.size_hint().unwrap_or(0), crate::MAX_PREALLOC);
let mut out = Vec::with_capacity(cap);
while let Some(b) = seq.next_element::<u8>()? {
out.push(b);
}
Ok(out)
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
let mut vec: Option<Vec<u8>> = None;
while let Some(key) = map.next_key::<String>()? {
if key == "vec" {
if vec.is_some() {
return Err(de::Error::duplicate_field("vec"));
}
vec = Some(map.next_value::<Vec<u8>>()?);
} else {
let _: de::IgnoredAny = map.next_value()?;
}
}
vec.ok_or_else(|| de::Error::missing_field("vec"))
}
}
deserializer.deserialize_any(CompatVisitor)
}
}
pub struct VLByteSlice<'a>(pub &'a [u8]);
impl fmt::Debug for VLByteSlice<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "VLByteSlice {{ ")?;
write_hex(f, self.0)?;
write!(f, " }}")
}
}
impl VLByteSlice<'_> {
#[inline(always)]
pub fn as_slice(&self) -> &[u8] {
self.0
}
}
impl Size for &VLByteSlice<'_> {
#[inline]
fn tls_serialized_len(&self) -> usize {
tls_serialize_bytes_len(self.0)
}
}
impl Size for VLByteSlice<'_> {
#[inline]
fn tls_serialized_len(&self) -> usize {
tls_serialize_bytes_len(self.0)
}
}
impl SerializeBytes for ContentLength {
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
SerializeBytes::tls_serialize_bytes(&self.0)
}
}
impl SerializeBytes for VLByteSlice<'_> {
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, Error> {
let content_len = self.0.len();
let content_length = ContentLength::from_usize(content_len)?;
let len_len = content_length.tls_serialized_len();
let total_len = crate::checked_alloc_len(content_len, len_len)?;
let mut out = alloc::vec::Vec::with_capacity(total_len);
out.append(&mut SerializeBytes::tls_serialize_bytes(&content_length)?);
out.extend(self.0);
Ok(out)
}
}
#[cfg(feature = "std")]
pub mod rw {
use super::*;
use crate::{Deserialize, Serialize};
impl Deserialize for ContentLength {
#[inline(always)]
fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, Error> {
ContentLength::new(crate::TlsVarInt::tls_deserialize(bytes)?)
}
}
impl Serialize for ContentLength {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
Serialize::tls_serialize(&self.0, writer)
}
}
#[inline]
pub fn read_length<R: std::io::Read>(bytes: &mut R) -> Result<(usize, usize), Error> {
let length = ContentLength::tls_deserialize(bytes)?;
let len_len = length.0.bytes_len();
let length: usize = length.0.value().try_into()?;
Ok((length, len_len))
}
impl<T: Deserialize> Deserialize for Vec<T> {
#[inline(always)]
fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, Error> {
let (length, _len_len) = read_length(bytes)?;
if length == 0 {
return Ok(Vec::new());
}
let mut sub = std::io::Read::take(bytes, length as u64);
let mut result = Vec::new();
while sub.limit() > 0 {
let before = sub.limit();
let element = T::tls_deserialize(&mut sub)?;
if sub.limit() == before {
return Err(Error::DecodingError(
"Vector element consumed 0 bytes; refusing to loop".into(),
));
}
result.push(element);
}
Ok(result)
}
}
#[inline(always)]
pub fn write_length<W: std::io::Write>(
writer: &mut W,
content_length: usize,
) -> Result<usize, Error> {
Serialize::tls_serialize(&ContentLength::from_usize(content_length)?, writer)
}
impl<T: Serialize + std::fmt::Debug> Serialize for Vec<T> {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
self.as_slice().tls_serialize(writer)
}
}
impl<T: Serialize + std::fmt::Debug> Serialize for &[T] {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
let content_length = self.iter().try_fold(0usize, |acc, e| {
crate::checked_len_add(acc, e.tls_serialized_len())
})?;
let len_len = write_length(writer, content_length)?;
#[cfg(debug_assertions)]
let mut written = 0;
for e in self.iter() {
#[cfg(debug_assertions)]
{
written += e.tls_serialize(writer)?;
}
#[cfg(not(debug_assertions))]
e.tls_serialize(writer)?;
}
#[cfg(debug_assertions)]
if written != content_length {
return Err(Error::LibraryError);
}
crate::checked_len_add(content_length, len_len)
}
}
}
#[cfg(feature = "std")]
mod rw_bytes {
use super::*;
use crate::{Deserialize, Serialize, read_bytes_bounded};
#[inline(always)]
fn tls_serialize_bytes<W: std::io::Write>(
writer: &mut W,
bytes: &[u8],
) -> Result<usize, Error> {
let content_length = bytes.len();
let len_len =
Serialize::tls_serialize(&ContentLength::from_usize(content_length)?, writer)?;
writer.write_all(bytes)?;
Ok(content_length + len_len)
}
impl Serialize for VLBytes {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
tls_serialize_bytes(writer, self.as_slice())
}
}
impl Serialize for &VLBytes {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
Serialize::tls_serialize(*self, writer)
}
}
impl Deserialize for VLBytes {
fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, Error> {
let length = ContentLength::tls_deserialize(bytes)?;
if length.0.value() == 0 {
return Ok(Self::new(vec![]));
}
let len: usize = length.0.value().try_into()?;
let vec = read_bytes_bounded(bytes, len)?;
Ok(Self { vec })
}
}
impl Serialize for VLByteVec {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
tls_serialize_bytes(writer, self.as_slice())
}
}
impl Serialize for &VLByteVec {
#[inline(always)]
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
(*self).tls_serialize(writer)
}
}
impl Deserialize for VLByteVec {
fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, Error> {
let length = ContentLength::tls_deserialize(bytes)?;
if length.0.value() == 0 {
return Ok(Self::new(vec![]));
}
let len: usize = length.0.value().try_into()?;
let vec = read_bytes_bounded(bytes, len)?;
Ok(Self { vec })
}
}
impl Serialize for &VLByteSlice<'_> {
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
tls_serialize_bytes(writer, self.0)
}
}
impl Serialize for VLByteSlice<'_> {
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
tls_serialize_bytes(writer, self.0)
}
}
}
#[cfg(feature = "std")]
mod secret_bytes {
use super::*;
use crate::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[cfg_attr(
feature = "future_deprecations",
deprecated(
note = "Use `SecretVLByteVec` instead. The serde format of `SecretVLByteVec` is not \
compatible with `SecretVLBytes`."
)
)]
pub struct SecretVLBytes(VLBytes);
impl SecretVLBytes {
pub fn new(vec: Vec<u8>) -> Self {
Self(VLBytes { vec })
}
fn vec(&self) -> &[u8] {
&self.0.vec
}
fn vec_mut(&mut self) -> &mut Vec<u8> {
&mut self.0.vec
}
}
impl_vl_bytes_generic!(SecretVLBytes);
impl Zeroize for SecretVLBytes {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl Drop for SecretVLBytes {
fn drop(&mut self) {
self.zeroize();
}
}
impl ZeroizeOnDrop for SecretVLBytes {}
impl Size for SecretVLBytes {
fn tls_serialized_len(&self) -> usize {
self.0.tls_serialized_len()
}
}
impl DeserializeBytes for SecretVLBytes {
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error>
where
Self: Sized,
{
let (bytes, remainder) = VLBytes::tls_deserialize_bytes(bytes)?;
Ok((Self(bytes), remainder))
}
}
impl Serialize for SecretVLBytes {
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
Serialize::tls_serialize(&self.0, writer)
}
}
impl Deserialize for SecretVLBytes {
fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, Error>
where
Self: Sized,
{
Ok(Self(VLBytes::tls_deserialize(bytes)?))
}
}
}
#[cfg(feature = "std")]
pub use secret_bytes::SecretVLBytes;
#[cfg(feature = "std")]
mod secret_byte_vec {
use super::*;
use crate::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct SecretVLByteVec(VLByteVec);
impl SecretVLByteVec {
pub fn new(vec: Vec<u8>) -> Self {
Self(VLByteVec { vec })
}
fn vec(&self) -> &[u8] {
&self.0.vec
}
fn vec_mut(&mut self) -> &mut Vec<u8> {
&mut self.0.vec
}
}
impl_vl_bytes_generic!(SecretVLByteVec);
impl Zeroize for SecretVLByteVec {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl Drop for SecretVLByteVec {
fn drop(&mut self) {
self.zeroize();
}
}
impl ZeroizeOnDrop for SecretVLByteVec {}
impl Size for SecretVLByteVec {
fn tls_serialized_len(&self) -> usize {
self.0.tls_serialized_len()
}
}
impl DeserializeBytes for SecretVLByteVec {
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error>
where
Self: Sized,
{
let (bytes, remainder) = VLByteVec::tls_deserialize_bytes(bytes)?;
Ok((Self(bytes), remainder))
}
}
impl Serialize for SecretVLByteVec {
fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
self.0.tls_serialize(writer)
}
}
impl Deserialize for SecretVLByteVec {
fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, Error>
where
Self: Sized,
{
Ok(Self(VLByteVec::tls_deserialize(bytes)?))
}
}
}
#[cfg(feature = "std")]
pub use secret_byte_vec::SecretVLByteVec;
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for VLBytes {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let mut vec = Vec::arbitrary(u)?;
vec.truncate(ContentLength::MAX as usize);
Ok(Self { vec })
}
}
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for VLByteVec {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let mut vec = Vec::arbitrary(u)?;
vec.truncate(ContentLength::MAX as usize);
Ok(Self { vec })
}
}
#[cfg(feature = "std")]
#[cfg(test)]
mod test {
use crate::{SecretVLBytes, VLByteSlice, VLBytes};
use std::println;
#[test]
fn test_debug() {
let tests = [
(vec![], "b\"\""),
(vec![0x00], "0x00"),
(vec![0xAA], "0xaa"),
(vec![0xFF], "0xff"),
(vec![0x00, 0x00], "0x0000"),
(vec![0x00, 0xAA], "0x00aa"),
(vec![0x00, 0xFF], "0x00ff"),
(vec![0xff, 0xff], "0xffff"),
];
for (test, expected) in tests.into_iter() {
println!("\n# {test:?}");
let expected_vl_byte_slice = format!("VLByteSlice {{ {expected} }}");
let got = format!("{:?}", VLByteSlice(&test));
println!("{got}");
assert_eq!(expected_vl_byte_slice, got);
let expected_vl_bytes = format!("VLBytes {{ {expected} }}");
let got = format!("{:?}", VLBytes::new(test.clone()));
println!("{got}");
assert_eq!(expected_vl_bytes, got);
let expected_secret_vl_bytes = format!("SecretVLBytes {{ {expected} }}");
let got = format!("{:?}", SecretVLBytes::new(test.clone()));
println!("{got}");
assert_eq!(expected_secret_vl_bytes, got);
}
}
}