use super::{Attribute, Block, Body, Structure};
use std::iter::FusedIterator;
use std::slice;
use std::vec;
macro_rules! impl_find_map_iterator {
($ty:ident$(<$lt:lifetime>)?, $item:ty, $map:expr) => {
impl$(<$lt>)* Iterator for $ty$(<$lt>)* {
type Item = $item;
fn next(&mut self) -> Option<Self::Item> {
self.iter.find_map($map)
}
}
impl$(<$lt>)* DoubleEndedIterator for $ty$(<$lt>)* {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
match self.iter.next_back() {
Some(val) => {
if let Some(val) = $map(val) {
return Some(val);
}
}
None => return None,
};
}
}
}
impl$(<$lt>)* FusedIterator for $ty$(<$lt>)* {}
};
}
macro_rules! impl_exact_size_iterator {
($ty:ident$(<$lt:lifetime>)?, $item:ty) => {
impl$(<$lt>)* Iterator for $ty$(<$lt>)* {
type Item = $item;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl$(<$lt>)* DoubleEndedIterator for $ty$(<$lt>)* {
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back()
}
}
impl$(<$lt>)* ExactSizeIterator for $ty$(<$lt>)* {
fn len(&self) -> usize {
self.iter.len()
}
}
impl$(<$lt>)* FusedIterator for $ty$(<$lt>)* {}
};
}
impl<T> Extend<T> for Body
where
T: Into<Structure>,
{
fn extend<I>(&mut self, iterable: I)
where
I: IntoIterator<Item = T>,
{
self.0.extend(iterable.into_iter().map(Into::into));
}
}
impl<T> FromIterator<T> for Body
where
T: Into<Structure>,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
let iter = iter.into_iter();
let lower = iter.size_hint().0;
let mut body = Body(Vec::with_capacity(lower));
body.extend(iter);
body
}
}
impl IntoIterator for Body {
type Item = Structure;
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
}
impl<'a> IntoIterator for &'a Body {
type Item = &'a Structure;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a mut Body {
type Item = &'a mut Structure;
type IntoIter = IterMut<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
#[derive(Debug, Clone)]
pub struct Iter<'a> {
iter: slice::Iter<'a, Structure>,
}
impl<'a> Iter<'a> {
pub(super) fn new(body: &'a Body) -> Iter<'a> {
Iter {
iter: body.0.iter(),
}
}
}
impl_exact_size_iterator!(Iter<'a>, &'a Structure);
#[derive(Debug)]
pub struct IterMut<'a> {
iter: slice::IterMut<'a, Structure>,
}
impl<'a> IterMut<'a> {
pub(super) fn new(body: &'a mut Body) -> IterMut<'a> {
IterMut {
iter: body.0.iter_mut(),
}
}
}
impl_exact_size_iterator!(IterMut<'a>, &'a mut Structure);
#[derive(Debug, Clone)]
pub struct IntoIter {
iter: vec::IntoIter<Structure>,
}
impl IntoIter {
pub(super) fn new(body: Body) -> IntoIter {
IntoIter {
iter: body.0.into_iter(),
}
}
}
impl_exact_size_iterator!(IntoIter, Structure);
#[derive(Debug, Clone)]
pub struct Attributes<'a> {
iter: Iter<'a>,
}
impl<'a> Attributes<'a> {
pub(super) fn new(body: &'a Body) -> Attributes<'a> {
Attributes { iter: body.iter() }
}
}
impl_find_map_iterator!(Attributes<'a>, &'a Attribute, Structure::as_attribute);
#[derive(Debug)]
pub struct AttributesMut<'a> {
iter: IterMut<'a>,
}
impl<'a> AttributesMut<'a> {
pub(super) fn new(body: &'a mut Body) -> AttributesMut<'a> {
AttributesMut {
iter: body.iter_mut(),
}
}
}
impl_find_map_iterator!(
AttributesMut<'a>,
&'a mut Attribute,
Structure::as_attribute_mut
);
#[derive(Debug, Clone)]
pub struct IntoAttributes {
iter: IntoIter,
}
impl IntoAttributes {
pub(super) fn new(body: Body) -> IntoAttributes {
IntoAttributes {
iter: body.into_iter(),
}
}
}
impl_find_map_iterator!(IntoAttributes, Attribute, Structure::into_attribute);
#[derive(Debug, Clone)]
pub struct Blocks<'a> {
iter: Iter<'a>,
}
impl<'a> Blocks<'a> {
pub(super) fn new(body: &'a Body) -> Blocks<'a> {
Blocks { iter: body.iter() }
}
}
impl_find_map_iterator!(Blocks<'a>, &'a Block, Structure::as_block);
#[derive(Debug)]
pub struct BlocksMut<'a> {
iter: IterMut<'a>,
}
impl<'a> BlocksMut<'a> {
pub(super) fn new(body: &'a mut Body) -> BlocksMut<'a> {
BlocksMut {
iter: body.iter_mut(),
}
}
}
impl_find_map_iterator!(BlocksMut<'a>, &'a mut Block, Structure::as_block_mut);
#[derive(Debug, Clone)]
pub struct IntoBlocks {
iter: IntoIter,
}
impl IntoBlocks {
pub(super) fn new(body: Body) -> IntoBlocks {
IntoBlocks {
iter: body.into_iter(),
}
}
}
impl_find_map_iterator!(IntoBlocks, Block, Structure::into_block);