use crate::{
arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag,
Header, Length, Reader, Result, Tag, ValueOrd, Writer,
};
use core::cmp::Ordering;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SequenceOf<T, const N: usize> {
inner: ArrayVec<T, N>,
}
impl<T, const N: usize> SequenceOf<T, N> {
pub fn new() -> Self {
Self {
inner: ArrayVec::new(),
}
}
pub fn add(&mut self, element: T) -> Result<()> {
self.inner.add(element)
}
pub fn get(&self, index: usize) -> Option<&T> {
self.inner.get(index)
}
pub fn iter(&self) -> SequenceOfIter<'_, T> {
SequenceOfIter {
inner: self.inner.iter(),
}
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn len(&self) -> usize {
self.inner.len()
}
}
impl<T, const N: usize> Default for SequenceOf<T, N> {
fn default() -> Self {
Self::new()
}
}
impl<'a, T, const N: usize> DecodeValue<'a> for SequenceOf<T, N>
where
T: Decode<'a>,
{
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
reader.read_nested(header.length, |reader| {
let mut sequence_of = Self::new();
while !reader.is_finished() {
sequence_of.add(T::decode(reader)?)?;
}
Ok(sequence_of)
})
}
}
impl<T, const N: usize> EncodeValue for SequenceOf<T, N>
where
T: Encode,
{
fn value_len(&self) -> Result<Length> {
self.iter()
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
for elem in self.iter() {
elem.encode(writer)?;
}
Ok(())
}
}
impl<T, const N: usize> FixedTag for SequenceOf<T, N> {
const TAG: Tag = Tag::Sequence;
}
impl<T, const N: usize> ValueOrd for SequenceOf<T, N>
where
T: DerOrd,
{
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
iter_cmp(self.iter(), other.iter())
}
}
#[derive(Clone, Debug)]
pub struct SequenceOfIter<'a, T> {
inner: arrayvec::Iter<'a, T>,
}
impl<'a, T> Iterator for SequenceOfIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next()
}
}
impl<'a, T> ExactSizeIterator for SequenceOfIter<'a, T> {}
impl<'a, T, const N: usize> DecodeValue<'a> for [T; N]
where
T: Decode<'a>,
{
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
let sequence_of = SequenceOf::<T, N>::decode_value(reader, header)?;
if sequence_of.inner.len() == N {
Ok(sequence_of
.inner
.into_array()
.map(|elem| elem.expect("arrayvec length mismatch")))
} else {
Err(Self::TAG.length_error())
}
}
}
impl<T, const N: usize> EncodeValue for [T; N]
where
T: Encode,
{
fn value_len(&self) -> Result<Length> {
self.iter()
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
for elem in self {
elem.encode(writer)?;
}
Ok(())
}
}
impl<T, const N: usize> FixedTag for [T; N] {
const TAG: Tag = Tag::Sequence;
}
impl<T, const N: usize> ValueOrd for [T; N]
where
T: DerOrd,
{
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
iter_cmp(self.iter(), other.iter())
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a, T> DecodeValue<'a> for Vec<T>
where
T: Decode<'a>,
{
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
reader.read_nested(header.length, |reader| {
let mut sequence_of = Self::new();
while !reader.is_finished() {
sequence_of.push(T::decode(reader)?);
}
Ok(sequence_of)
})
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> EncodeValue for Vec<T>
where
T: Encode,
{
fn value_len(&self) -> Result<Length> {
self.iter()
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
for elem in self {
elem.encode(writer)?;
}
Ok(())
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> FixedTag for Vec<T> {
const TAG: Tag = Tag::Sequence;
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> ValueOrd for Vec<T>
where
T: DerOrd,
{
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
iter_cmp(self.iter(), other.iter())
}
}