pub use std::collections::VecDeque;
pub use std::collections::{btree_set, BTreeSet};
pub use std::collections::{hash_map, HashMap, HashSet};
-pub use std::convert::{TryFrom, TryInto};
+pub use std::convert::{Infallible, TryFrom, TryInto};
pub use std::env;
pub use std::error::Error;
pub use std::fmt::Formatter;
}
}
}
+
+#[derive(Debug)]
+pub enum Loop<E> {
+ Continue,
+ Break,
+ Error(E),
+}
+impl<E> From<E> for Loop<E> {
+ fn from(e: E) -> Loop<E> { Loop::Error(e) }
+}
+
+pub trait IteratorExt<'f,U,E,F>: Iterator
+ where F: 'f + FnMut(Self::Item) -> Result<U,Loop<E>>,
+{
+ type R1: Iterator<Item=U>;
+ fn map_loop(self, f: F) -> Self::R1 where E: EmptyType;
+/*
+ fn try_map_loop<
+ U, E,
+ F: FnMut(Self::Item) -> Result<U,Loop<E>>
+ >(self, f: &mut F) -> impl Iterator<Result<U>> {
+ self
+ .map(f)
+ .filter(|i| matches!(i, Err(Loop::Continue)))
+ .take_while(|i| matches!(i, Err(Loop::Break)))
+ .map(|i| match i {
+ Ok(y) => Ok(y),
+ Err(Loop::Error(e)) => Err(e),
+ _ => panic!(),
+ })
+ }*/
+}
+
+pub trait EmptyType { fn diverge<T>(self) -> T; }
+
+impl EmptyType for Infallible {
+ fn diverge<T>(self) -> T { match self { } }
+}
+
+impl<'f,T,U,E,F> IteratorExt<'f,U,E,F> for T where
+ T: 'f + Iterator,
+ F: 'f + FnMut(Self::Item) -> Result<U,Loop<E>>,
+{
+ type R1 = impl Iterator<Item=U> + 'f;
+ fn map_loop(self, f: F) -> Self::R1 where E: EmptyType {
+ self
+ .map(f)
+ .filter(|i| !matches!(i, Err(Loop::Continue)))
+ .take_while(|i| !matches!(i, Err(Loop::Break)))
+ .map(|i| i.ok().unwrap())
+ }
+}