use std::io;
use crate::pull_parser::{
v7400::attribute::{loader::LoadAttribute, Attributes},
ParserSource, Result,
};
fn make_size_hint_for_attrs<R, V>(
attributes: &Attributes<'_, R>,
loaders: &impl Iterator<Item = V>,
) -> (usize, Option<usize>)
where
R: ParserSource,
V: LoadAttribute,
{
let (loaders_min, loaders_max) = loaders.size_hint();
let attrs_rest = attributes.rest_count() as usize;
let min = std::cmp::min(attrs_rest, loaders_min);
let max = loaders_max.map_or_else(usize::max_value, |v| std::cmp::min(attrs_rest, v));
(min, Some(max))
}
fn load_next<R, V>(
attributes: &mut Attributes<'_, R>,
loaders: &mut impl Iterator<Item = V>,
) -> Option<Result<V::Output>>
where
R: ParserSource,
V: LoadAttribute,
{
let loader = loaders.next()?;
match attributes.load_next(loader) {
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
fn load_next_buffered<R, V>(
attributes: &mut Attributes<'_, R>,
loaders: &mut impl Iterator<Item = V>,
) -> Option<Result<V::Output>>
where
R: ParserSource + io::BufRead,
V: LoadAttribute,
{
let loader = loaders.next()?;
match attributes.load_next_buffered(loader) {
Ok(Some(v)) => Some(Ok(v)),
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
#[derive(Debug)]
pub struct BorrowedIter<'a, 'r, R, I> {
attributes: &'a mut Attributes<'r, R>,
loaders: I,
}
impl<'a, 'r, R, I, V> BorrowedIter<'a, 'r, R, I>
where
R: ParserSource,
I: Iterator<Item = V>,
V: LoadAttribute,
{
pub(crate) fn new(attributes: &'a mut Attributes<'r, R>, loaders: I) -> Self {
Self {
attributes,
loaders,
}
}
}
impl<'a, 'r, R, I, V> Iterator for BorrowedIter<'a, 'r, R, I>
where
R: ParserSource,
I: Iterator<Item = V>,
V: LoadAttribute,
{
type Item = Result<V::Output>;
fn next(&mut self) -> Option<Self::Item> {
load_next(&mut self.attributes, &mut self.loaders)
}
fn size_hint(&self) -> (usize, Option<usize>) {
make_size_hint_for_attrs(&self.attributes, &self.loaders)
}
}
#[derive(Debug)]
pub struct BorrowedIterBuffered<'a, 'r, R, I> {
attributes: &'a mut Attributes<'r, R>,
loaders: I,
}
impl<'a, 'r, R, I, V> BorrowedIterBuffered<'a, 'r, R, I>
where
R: ParserSource,
I: Iterator<Item = V>,
V: LoadAttribute,
{
pub(crate) fn new(attributes: &'a mut Attributes<'r, R>, loaders: I) -> Self {
Self {
attributes,
loaders,
}
}
}
impl<'a, 'r, R, I, V> Iterator for BorrowedIterBuffered<'a, 'r, R, I>
where
R: ParserSource + io::BufRead,
I: Iterator<Item = V>,
V: LoadAttribute,
{
type Item = Result<V::Output>;
fn next(&mut self) -> Option<Self::Item> {
load_next_buffered(&mut self.attributes, &mut self.loaders)
}
fn size_hint(&self) -> (usize, Option<usize>) {
make_size_hint_for_attrs(&self.attributes, &self.loaders)
}
}
#[derive(Debug)]
pub struct OwnedIter<'r, R, I> {
attributes: Attributes<'r, R>,
loaders: I,
}
impl<'r, R, I, V> OwnedIter<'r, R, I>
where
R: ParserSource,
I: Iterator<Item = V>,
V: LoadAttribute,
{
pub(crate) fn new(attributes: Attributes<'r, R>, loaders: I) -> Self {
Self {
attributes,
loaders,
}
}
}
impl<'r, R, I, V> Iterator for OwnedIter<'r, R, I>
where
R: ParserSource,
I: Iterator<Item = V>,
V: LoadAttribute,
{
type Item = Result<V::Output>;
fn next(&mut self) -> Option<Self::Item> {
load_next(&mut self.attributes, &mut self.loaders)
}
fn size_hint(&self) -> (usize, Option<usize>) {
make_size_hint_for_attrs(&self.attributes, &self.loaders)
}
}
#[derive(Debug)]
pub struct OwnedIterBuffered<'r, R, I> {
attributes: Attributes<'r, R>,
loaders: I,
}
impl<'r, R, I, V> OwnedIterBuffered<'r, R, I>
where
R: ParserSource,
I: Iterator<Item = V>,
V: LoadAttribute,
{
pub(crate) fn new(attributes: Attributes<'r, R>, loaders: I) -> Self {
Self {
attributes,
loaders,
}
}
}
impl<'r, R, I, V> Iterator for OwnedIterBuffered<'r, R, I>
where
R: ParserSource + io::BufRead,
I: Iterator<Item = V>,
V: LoadAttribute,
{
type Item = Result<V::Output>;
fn next(&mut self) -> Option<Self::Item> {
load_next_buffered(&mut self.attributes, &mut self.loaders)
}
fn size_hint(&self) -> (usize, Option<usize>) {
make_size_hint_for_attrs(&self.attributes, &self.loaders)
}
}