use super::CborIter;
use crate::Cbor;
use std::{
borrow::Cow,
fmt::{Debug, Display, Formatter, Write},
io::Read,
};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct StringIter<'a>(CborIter<'a>);
impl<'a> StringIter<'a> {
pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
Self(CborIter::new(bytes, len))
}
pub fn is_indefinite(&self) -> bool {
self.0.size().is_none()
}
pub fn is_empty(&self) -> bool {
let mut this = *self;
this.next().is_none()
}
pub fn as_str(&self) -> Option<&'a str> {
let mut this = *self;
if let Some(first) = this.next() {
if this.next().is_none() {
Some(first)
} else {
None
}
} else {
Some("")
}
}
pub fn as_cow(&self) -> Cow<'a, str> {
if let Some(s) = self.as_str() {
Cow::Borrowed(s)
} else {
Cow::Owned(self.collect())
}
}
pub fn len(&self) -> usize {
self.map(|v| v.len()).sum()
}
}
impl<'a> Debug for StringIter<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("StringIter")
}
}
impl<'a> Display for StringIter<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
for s in *self {
f.write_str(s)?;
}
Ok(())
}
}
impl<'a> Iterator for StringIter<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
let v = self
.0
.next()?
.0
.expect("string fragments must be in definite size encoding");
Some(unsafe { std::str::from_utf8_unchecked(v) })
}
}
impl<'a, S: AsRef<str>> PartialEq<S> for StringIter<'a> {
fn eq(&self, other: &S) -> bool {
let this = *self;
let mut other = other.as_ref();
for prefix in this {
if other.starts_with(prefix) {
other = &other[prefix.len()..];
} else {
return false;
}
}
other.is_empty()
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct BytesIter<'a>(CborIter<'a>, &'a [u8]);
impl<'a> BytesIter<'a> {
pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
Self(CborIter::new(bytes, len), b"")
}
pub fn is_indefinite(&self) -> bool {
self.0.size().is_none()
}
pub fn is_empty(&self) -> bool {
let mut this = *self;
this.next().is_none()
}
pub fn as_slice(&self) -> Option<&'a [u8]> {
let mut this = *self;
if let Some(first) = this.next() {
if this.next().is_none() {
Some(first)
} else {
None
}
} else {
Some(b"")
}
}
pub fn as_cow(&self) -> Cow<'a, [u8]> {
if let Some(s) = self.as_slice() {
Cow::Borrowed(s)
} else {
let mut v = Vec::new();
for b in *self {
v.extend_from_slice(b);
}
Cow::Owned(v)
}
}
pub fn to_vec(self) -> Vec<u8> {
let mut ret = Vec::new();
for v in self {
ret.extend_from_slice(v);
}
ret
}
pub fn len(&self) -> usize {
self.map(|v| v.len()).sum()
}
}
impl<'a> Debug for BytesIter<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("BytesIter")
}
}
impl<'a> Display for BytesIter<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut first = true;
for b in *self {
if first {
first = false;
} else {
f.write_char(' ')?;
}
for byte in b {
write!(f, "{:02x}", byte)?;
}
}
Ok(())
}
}
impl<'a> Iterator for BytesIter<'a> {
type Item = &'a [u8];
fn next(&mut self) -> Option<Self::Item> {
Some(
self.0
.next()?
.0
.expect("byte string fragments must be in definite size encoding"),
)
}
}
impl<'a> Read for BytesIter<'a> {
fn read(&mut self, mut buf: &mut [u8]) -> std::io::Result<usize> {
let mut in_hand = self.1;
let mut read = 0;
loop {
let transfer = in_hand.len().min(buf.len());
let (left, right) = buf.split_at_mut(transfer);
left.copy_from_slice(&in_hand[..transfer]);
in_hand = &in_hand[transfer..];
buf = right;
read += transfer;
if buf.is_empty() {
break;
}
if let Some(bytes) = self.next() {
in_hand = bytes;
} else {
break;
}
}
self.1 = in_hand;
Ok(read)
}
}
impl<'a, S: AsRef<[u8]>> PartialEq<S> for BytesIter<'a> {
fn eq(&self, other: &S) -> bool {
let this = *self;
let mut other = other.as_ref();
for prefix in this {
if other.starts_with(prefix) {
other = &other[prefix.len()..];
} else {
return false;
}
}
other.is_empty()
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ArrayIter<'a>(CborIter<'a>);
impl<'a> ArrayIter<'a> {
pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
Self(CborIter::new(bytes, len))
}
pub fn size(&self) -> Option<u64> {
self.0.size()
}
}
impl<'a> Debug for ArrayIter<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("ArrayIter")
}
}
impl<'a> Iterator for ArrayIter<'a> {
type Item = &'a Cbor;
fn next(&mut self) -> Option<Self::Item> {
Some(self.0.next()?.1)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct DictIter<'a>(CborIter<'a>);
impl<'a> DictIter<'a> {
pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
Self(CborIter::new(bytes, len.map(|x| x * 2)))
}
pub fn size(&self) -> Option<u64> {
self.0.size().map(|x| x / 2)
}
}
impl<'a> Debug for DictIter<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("DictIter")
}
}
impl<'a> Iterator for DictIter<'a> {
type Item = (&'a Cbor, &'a Cbor);
fn next(&mut self) -> Option<Self::Item> {
Some((self.0.next()?.1, self.0.next()?.1))
}
}