use std::marker::PhantomData;
use lender::{DoubleEndedLender, Lend, Lender, Lending};
use crate::traits::Pair;
pub trait NodeLabelsLender<'lend, __ImplBound: lender::ImplBound = lender::Ref<'lend, Self>>:
Lender + Lending<'lend, __ImplBound, Lend = (usize, Self::IntoIterator)>
{
type Label;
type IntoIterator: IntoIterator<Item = Self::Label>;
fn into_labeled_pairs<'a>(self) -> IntoLabeledPairs<'a, Self>
where
Self: Sized + for<'b> NodeLabelsLender<'b, Label: Pair<Left = usize>>,
{
self.into()
}
fn into_pairs<'a>(self) -> IntoPairs<'a, Self>
where
Self: Sized + for<'b> NodeLabelsLender<'b, Label = usize>,
{
self.into()
}
}
pub struct IntoLabeledPairs<'a, L: for<'b> NodeLabelsLender<'b, Label: Pair<Left = usize>> + 'a> {
lender: Box<L>,
current_node: usize,
current_iter: Option<LenderIntoIter<'a, L>>,
_marker: PhantomData<&'a L>, }
impl<L: for<'b> NodeLabelsLender<'b, Label: Pair<Left = usize>>> std::fmt::Debug
for IntoLabeledPairs<'_, L>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IntoLabeledPairs")
.field("current_node", &self.current_node)
.finish_non_exhaustive()
}
}
impl<'a, L: for<'b> NodeLabelsLender<'b, Label: Pair<Left = usize, Right: Copy>>> Iterator
for IntoLabeledPairs<'a, L>
{
type Item = (
(usize, usize),
<<L as NodeLabelsLender<'a>>::Label as Pair>::Right,
);
fn next(
&mut self,
) -> Option<(
(usize, usize),
<<L as NodeLabelsLender<'a>>::Label as Pair>::Right,
)> {
loop {
if let Some(inner) = &mut self.current_iter {
if let Some((dst, label)) = inner.next().map(Pair::into_pair) {
return Some(((self.current_node, dst), label));
}
}
if let Some((next_node, next_iter)) = self.lender.next().map(|(x, it)| {
(x, unsafe {
std::mem::transmute::<LenderIntoIter<'_, L>, LenderIntoIter<'_, L>>(
it.into_iter(),
)
})
}) {
self.current_node = next_node;
self.current_iter = Some(next_iter);
} else {
return None;
}
}
}
}
impl<'a, L> From<L> for IntoLabeledPairs<'a, L>
where
L: Sized + for<'b> NodeLabelsLender<'b, Label: Pair<Left = usize>>,
{
fn from(lender: L) -> Self {
IntoLabeledPairs {
lender: Box::new(lender),
current_node: 0,
current_iter: None,
_marker: PhantomData,
}
}
}
pub struct IntoPairs<'a, L: for<'b> NodeLabelsLender<'b, Label = usize>> {
lender: Box<L>,
current_node: usize,
current_iter: Option<LenderIntoIter<'a, L>>,
_marker: PhantomData<&'a L>, }
impl<'a, L: for<'b> NodeLabelsLender<'b, Label = usize>> Iterator for IntoPairs<'a, L> {
type Item = (usize, usize);
fn next(&mut self) -> Option<(usize, usize)> {
loop {
if let Some(inner) = &mut self.current_iter {
if let Some(dst) = inner.next() {
return Some((self.current_node, dst));
}
}
if let Some((next_node, next_iter)) = self.lender.next().map(|(x, it)| {
(x, unsafe {
std::mem::transmute::<LenderIntoIter<'_, L>, LenderIntoIter<'_, L>>(
it.into_iter(),
)
})
}) {
self.current_node = next_node;
self.current_iter = Some(next_iter);
} else {
return None;
}
}
}
}
impl<'a, L> From<L> for IntoPairs<'a, L>
where
L: Sized + for<'b> NodeLabelsLender<'b, Label = usize>,
{
fn from(lender: L) -> Self {
IntoPairs {
lender: Box::new(lender),
current_node: 0,
current_iter: None,
_marker: PhantomData,
}
}
}
pub type LenderLabel<'lend, L> = <L as NodeLabelsLender<'lend>>::Label;
pub type LenderIntoIterator<'lend, L> = <L as NodeLabelsLender<'lend>>::IntoIterator;
pub type LenderIntoIter<'lend, L> =
<<L as NodeLabelsLender<'lend>>::IntoIterator as IntoIterator>::IntoIter;
impl<'lend, A, B> NodeLabelsLender<'lend> for lender::Chain<A, B>
where
A: Lender + for<'next> NodeLabelsLender<'next>,
B: Lender
+ for<'next> NodeLabelsLender<
'next,
Label = <A as NodeLabelsLender<'next>>::Label,
IntoIterator = <A as NodeLabelsLender<'next>>::IntoIterator,
>,
{
type Label = <A as NodeLabelsLender<'lend>>::Label;
type IntoIterator = <A as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, T> NodeLabelsLender<'lend> for lender::Chunk<'_, T>
where
T: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = <T as NodeLabelsLender<'lend>>::Label;
type IntoIterator = <T as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::Cycle<L>
where
L: Clone + Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<Label, II, L> NodeLabelsLender<'_> for lender::Enumerate<L>
where
L: Lender,
L: for<'all> Lending<'all, Lend = II>,
II: IntoIterator<Item = Label>,
{
type Label = Label;
type IntoIterator = II;
}
impl<'lend, L, P> NodeLabelsLender<'lend> for lender::Filter<L, P>
where
P: for<'next> FnMut(&(usize, <L as NodeLabelsLender<'next>>::IntoIterator)) -> bool,
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<L, F, II> NodeLabelsLender<'_> for lender::FilterMap<L, F>
where
II: IntoIterator,
F: for<'all> lender::higher_order::FnMutHKAOpt<'all, Lend<'all, L>, B = (usize, II)>,
L: Lender,
{
type Label = II::Item;
type IntoIterator = II;
}
impl<'lend, LL, L, F> NodeLabelsLender<'lend> for lender::FlatMap<'_, LL, F>
where
LL: Lender,
L: Lender + for<'next> NodeLabelsLender<'next> + 'lend,
F: for<'all> lender::higher_order::FnMutHKA<'all, Lend<'all, LL>, B = L>,
{
type Label = <L as NodeLabelsLender<'lend>>::Label;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, LL, L> NodeLabelsLender<'lend> for lender::Flatten<'_, LL>
where
LL: Lender<Lend = L>,
L: Lender + for<'next> NodeLabelsLender<'next> + 'lend,
{
type Label = <L as NodeLabelsLender<'lend>>::Label;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::Fuse<L>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L, F> NodeLabelsLender<'lend> for lender::Inspect<L, F>
where
F: for<'next> FnMut(&Lend<'next, L>),
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<L, F, II> NodeLabelsLender<'_> for lender::Map<L, F>
where
F: for<'all> lender::higher_order::FnMutHKA<'all, Lend<'all, L>, B = (usize, II)>,
II: IntoIterator,
L: Lender,
{
type Label = II::Item;
type IntoIterator = II;
}
impl<L, P, II> NodeLabelsLender<'_> for lender::MapWhile<L, P>
where
P: for<'all> lender::higher_order::FnMutHKAOpt<'all, Lend<'all, L>, B = (usize, II)>,
II: IntoIterator,
L: Lender,
{
type Label = II::Item;
type IntoIterator = II;
}
impl<'lend, L, F> NodeLabelsLender<'lend> for lender::Mutate<L, F>
where
F: FnMut(&mut Lend<'_, L>),
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::Peekable<'_, L>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::Rev<L>
where
L: Lender + DoubleEndedLender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<L, St, F, II> NodeLabelsLender<'_> for lender::Scan<L, St, F>
where
for<'all> F:
lender::higher_order::FnMutHKAOpt<'all, (&'all mut St, Lend<'all, L>), B = (usize, II)>,
L: Lender,
II: IntoIterator,
{
type Label = II::Item;
type IntoIterator = II;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::Skip<L>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L, P> NodeLabelsLender<'lend> for lender::SkipWhile<L, P>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
P: for<'next> FnMut(&Lend<'next, L>) -> bool,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::StepBy<L>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L> NodeLabelsLender<'lend> for lender::Take<L>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<'lend, L, P> NodeLabelsLender<'lend> for lender::TakeWhile<L, P>
where
L: Lender + for<'next> NodeLabelsLender<'next>,
P: FnMut(&Lend<'_, L>) -> bool,
{
type Label = LenderLabel<'lend, L>;
type IntoIterator = <L as NodeLabelsLender<'lend>>::IntoIterator;
}
impl<A, B, II> NodeLabelsLender<'_> for lender::Zip<A, B>
where
A: Lender + for<'next> Lending<'next, Lend = usize>,
B: Lender + for<'next> Lending<'next, Lend = II>,
II: IntoIterator,
{
type Label = II::Item;
type IntoIterator = II;
}
impl<I, J> NodeLabelsLender<'_> for lender::FromIter<I>
where
I: Iterator<Item = (usize, J)>,
J: IntoIterator,
{
type Label = J::Item;
type IntoIterator = J;
}
impl<S, F, J> NodeLabelsLender<'_> for lender::FromFn<S, F>
where
F: for<'all> lender::higher_order::FnMutHKAOpt<'all, &'all mut S, B = (usize, J)>,
J: IntoIterator,
{
type Label = J::Item;
type IntoIterator = J;
}