use crate::{
DerOrd, Encode, EncodeValue, Error, FixedTag, Length, Tag, ValueOrd, Writer, ord::iter_cmp,
};
use core::cmp::Ordering;
#[cfg(any(feature = "alloc", feature = "heapless"))]
use crate::{Decode, DecodeValue, Header, Reader};
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "heapless")]
use {crate::ErrorKind, core::slice};
#[cfg(feature = "heapless")]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SequenceOf<T, const N: usize> {
inner: heapless::Vec<T, N>,
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> SequenceOf<T, N> {
#[must_use]
pub fn new() -> Self {
Self {
inner: heapless::Vec::new(),
}
}
pub fn add(&mut self, element: T) -> Result<(), Error> {
self.inner
.push(element)
.map_err(|_| ErrorKind::Overlength.into())
}
pub fn as_slice(&self) -> &[T] {
self.inner.as_slice()
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
self.inner.as_mut_slice()
}
pub fn get(&self, index: usize) -> Option<&T> {
self.inner.get(index)
}
pub fn into_inner(self) -> heapless::Vec<T, N> {
self.inner
}
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()
}
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> AsRef<[T]> for SequenceOf<T, N> {
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> AsMut<[T]> for SequenceOf<T, N> {
fn as_mut(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> Default for SequenceOf<T, N> {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "heapless")]
impl<'a, T, const N: usize> DecodeValue<'a> for SequenceOf<T, N>
where
T: Decode<'a>,
{
type Error = T::Error;
fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> Result<Self, Self::Error> {
let mut sequence_of = Self::new();
while !reader.is_finished() {
sequence_of.add(T::decode(reader)?)?;
}
Ok(sequence_of)
}
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> EncodeValue for SequenceOf<T, N>
where
T: Encode,
{
fn value_len(&self) -> Result<Length, Error> {
self.iter()
.try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
for elem in self.iter() {
elem.encode(writer)?;
}
Ok(())
}
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> FixedTag for SequenceOf<T, N> {
const TAG: Tag = Tag::Sequence;
}
#[cfg(feature = "heapless")]
impl<T, const N: usize> ValueOrd for SequenceOf<T, N>
where
T: DerOrd,
{
fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
iter_cmp(self.iter(), other.iter())
}
}
#[cfg(feature = "heapless")]
#[derive(Clone, Debug)]
pub struct SequenceOfIter<'a, T> {
inner: slice::Iter<'a, T>,
}
#[cfg(feature = "heapless")]
impl<'a, T: 'a> Iterator for SequenceOfIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[cfg(feature = "heapless")]
impl<'a, T: 'a> ExactSizeIterator for SequenceOfIter<'a, T> {}
impl<T: Encode> EncodeValue for [T] {
fn value_len(&self) -> Result<Length, Error> {
self.iter()
.try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
for elem in self {
elem.encode(writer)?;
}
Ok(())
}
}
#[cfg(feature = "heapless")]
impl<'a, T, const N: usize> DecodeValue<'a> for [T; N]
where
T: Decode<'a>,
{
type Error = T::Error;
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
let sequence_of = SequenceOf::<T, N>::decode_value(reader, header)?;
sequence_of
.inner
.into_array()
.map_err(|_| reader.error(Self::TAG.length_error()).into())
}
}
impl<T, const N: usize> EncodeValue for [T; N]
where
T: Encode,
{
fn value_len(&self) -> Result<Length, Error> {
self.iter()
.try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
self.as_slice().encode_value(writer)
}
}
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, Error> {
iter_cmp(self.iter(), other.iter())
}
}
#[cfg(feature = "alloc")]
impl<'a, T> DecodeValue<'a> for Vec<T>
where
T: Decode<'a>,
{
type Error = T::Error;
fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> Result<Self, Self::Error> {
let mut sequence_of = Vec::<T>::new();
while !reader.is_finished() {
sequence_of.push(T::decode(reader)?);
}
Ok(sequence_of)
}
}
#[cfg(feature = "alloc")]
impl<T> EncodeValue for Vec<T>
where
T: Encode,
{
fn value_len(&self) -> Result<Length, Error> {
self.iter()
.try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
self.as_slice().encode_value(writer)
}
}
#[cfg(feature = "alloc")]
impl<T> FixedTag for Vec<T> {
const TAG: Tag = Tag::Sequence;
}
#[cfg(feature = "alloc")]
impl<T> ValueOrd for Vec<T>
where
T: DerOrd,
{
fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
iter_cmp(self.iter(), other.iter())
}
}
#[cfg(all(test, feature = "heapless"))]
mod tests {
use super::SequenceOf;
use crate::ord::DerOrd;
#[test]
fn sequenceof_valueord_value_cmp() {
use core::cmp::Ordering;
let arr1 = {
let mut arr: SequenceOf<u16, 2> = SequenceOf::new();
arr.add(0u16).expect("element to be added");
arr.add(2u16).expect("element to be added");
arr
};
let arr2 = {
let mut arr: SequenceOf<u16, 2> = SequenceOf::new();
arr.add(0u16).expect("element to be added");
arr.add(1u16).expect("element to be added");
arr
};
assert_eq!(arr1.der_cmp(&arr2), Ok(Ordering::Greater));
}
}