use crate::{
arrayvec, ArrayVec, Decodable, DecodeValue, Decoder, DerOrd, Encodable, EncodeValue, Encoder,
ErrorKind, FixedTag, Length, Result, Tag,
};
use core::cmp::Ordering;
#[cfg(feature = "alloc")]
use {alloc::vec::Vec, core::slice};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct SetOf<T, const N: usize>
where
T: Clone + DerOrd,
{
inner: ArrayVec<T, N>,
}
impl<T, const N: usize> SetOf<T, N>
where
T: Clone + DerOrd,
{
pub fn new() -> Self {
Self {
inner: ArrayVec::default(),
}
}
pub fn add(&mut self, new_elem: T) -> Result<()> {
if let Some(last_elem) = self.inner.last() {
if new_elem.der_cmp(last_elem)? != Ordering::Greater {
return Err(ErrorKind::SetOrdering.into());
}
}
self.inner.add(new_elem)
}
pub fn get(&self, index: usize) -> Option<&T> {
self.inner.get(index)
}
pub fn iter(&self) -> SetOfIter<'_, T> {
SetOfIter {
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 SetOf<T, N>
where
T: Clone + DerOrd,
{
fn default() -> Self {
Self::new()
}
}
impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
where
T: Clone + Decodable<'a> + DerOrd,
{
fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
let end_pos = (decoder.position() + length)?;
let mut result = Self::new();
while decoder.position() < end_pos {
result.add(decoder.decode()?)?;
}
if decoder.position() != end_pos {
decoder.error(ErrorKind::Length { tag: Self::TAG });
}
Ok(result)
}
}
impl<'a, T, const N: usize> EncodeValue for SetOf<T, N>
where
T: 'a + Clone + Decodable<'a> + Encodable + DerOrd,
{
fn value_len(&self) -> Result<Length> {
self.iter()
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
for elem in self.iter() {
elem.encode(encoder)?;
}
Ok(())
}
}
impl<'a, T, const N: usize> FixedTag for SetOf<T, N>
where
T: Clone + Decodable<'a> + DerOrd,
{
const TAG: Tag = Tag::Set;
}
#[derive(Clone, Debug)]
pub struct SetOfIter<'a, T> {
inner: arrayvec::Iter<'a, T>,
}
impl<'a, T> Iterator for SetOfIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
pub struct SetOfVec<T>
where
T: Clone + DerOrd,
{
inner: Vec<T>,
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> SetOfVec<T>
where
T: Clone + DerOrd,
{
pub fn new() -> Self {
Self {
inner: Vec::default(),
}
}
pub fn add(&mut self, new_elem: T) -> Result<()> {
if let Some(last_elem) = self.inner.last() {
if new_elem.der_cmp(last_elem)? != Ordering::Greater {
return Err(ErrorKind::SetOrdering.into());
}
}
self.inner.push(new_elem);
Ok(())
}
pub fn get(&self, index: usize) -> Option<&T> {
self.inner.get(index)
}
pub fn iter(&self) -> slice::Iter<'_, T> {
self.inner.iter()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn len(&self) -> usize {
self.inner.len()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a, T> DecodeValue<'a> for SetOfVec<T>
where
T: Clone + Decodable<'a> + DerOrd,
{
fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
let end_pos = (decoder.position() + length)?;
let mut result = Self::new();
while decoder.position() < end_pos {
result.add(decoder.decode()?)?;
}
if decoder.position() != end_pos {
decoder.error(ErrorKind::Length { tag: Self::TAG });
}
Ok(result)
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<'a, T> EncodeValue for SetOfVec<T>
where
T: 'a + Clone + Decodable<'a> + Encodable + DerOrd,
{
fn value_len(&self) -> Result<Length> {
self.iter()
.fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
}
fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
for elem in self.iter() {
elem.encode(encoder)?;
}
Ok(())
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> FixedTag for SetOfVec<T>
where
T: Clone + DerOrd,
{
const TAG: Tag = Tag::Set;
}