use crate::{Decoder, Encodable, Encoder, ErrorKind, Header, Length, Result, Slice, Tag, TaggedSlice};
pub fn encoded_length( encodables: &[&dyn Encodable]) -> Result<Length> {
let inner_len = encoded_length_inner(encodables)?;
Header::new(crate::tag::MEANINGLESS_TAG, inner_len)?.encoded_length() + inner_len
}
pub(crate) fn encoded_length_inner(encodables: &[&dyn Encodable]) -> Result<Length> {
encodables
.iter()
.fold(Ok(Length::zero()), |sum, encodable| {
sum + encodable.encoded_length()?
})
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Nested<'a> {
pub(crate) tag: Tag,
pub(crate) slice: Slice<'a>,
}
impl<'a> Nested<'a> {
pub fn new(tag: Tag, slice: &'a [u8]) -> Result<Self> {
Slice::new(slice)
.map(|slice| Self { tag, slice })
.map_err(|_| ErrorKind::Length { tag }.into())
}
pub fn as_bytes(&self) -> &'a [u8] {
self.slice.as_bytes()
}
pub fn tag(&self) -> Tag {
self.tag
}
pub fn decode_nested<F, T>(&self, f: F) -> Result<T>
where
F: FnOnce(&mut Decoder<'a>) -> Result<T>,
{
let mut nested_decoder = Decoder::new(self.as_bytes());
let result = f(&mut nested_decoder)?;
nested_decoder.finish(result)
}
}
impl AsRef<[u8]> for Nested<'_> {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl<'a> From<TaggedSlice<'a>> for Nested<'a> {
fn from(tagged_slice: TaggedSlice<'a>) -> Nested<'a> {
Self { tag: tagged_slice.tag(), slice: tagged_slice.value }
}
}
impl<'a> From<Nested<'a>> for TaggedSlice<'a> {
fn from(nested: Nested<'a>) -> TaggedSlice<'a> {
TaggedSlice { tag: nested.tag(), value: nested.slice }
}
}
impl<'a> Encodable for Nested<'a> {
fn encoded_length(&self) -> Result<Length> {
TaggedSlice::from(*self).encoded_length()
}
fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()> {
TaggedSlice::from(*self).encode(encoder)
}
}