impl Session {
#[throws(Explode)]
fn pieces<PI:Idx>(&self) -> Pieces<PI> {
- let pieces = self.dom
- .element("#pieces_marker")
- .unwrap().next_siblings()
- .map_loop(|puse: ego_tree::NodeRef<scraper::Node>| {
+ let pieces = {
+ let mut pieces: Pieces<PI> = default();
+ for puse in self.dom
+ .element("#pieces_marker")
+ .unwrap().next_siblings()
+ {
let puse = puse.value();
- let puse = puse.as_element().ok_or(Loop::Continue)?;
- let attr = puse.attr("data-info").ok_or(Loop::Break)?;
+ if_let!{ Some(puse) = puse.as_element(); else continue; };
+ if_let!{ Some(attr) = puse.attr("data-info"); else break; };
let pos = Pos::from_iter(["x","y"].iter().map(|attr|{
puse
.attr(attr).unwrap()
let id = puse.id.as_ref().unwrap();
let id = id.strip_prefix("use").unwrap().to_string();
let info = serde_json::from_str(attr).unwrap();
- Loop::ok(PieceInfo { id, pos, info })
- })
- .collect();
+ pieces.push(PieceInfo { id, pos, info });
+ }
+ pieces
+ };
let nick = self.nick;
dbgc!(nick, &pieces);
pieces
}
}
-#[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) }
-}
-impl Loop<Infallible> {
- pub fn ok<T>(t: T) -> Result<T,Loop<Infallible>> { Ok(t) }
-}
-
-pub trait IteratorExt<U,E,F>: Iterator
- where F: FnMut(Self::Item) -> Result<U,Loop<E>>,
-{
- type Return: Iterator<Item=U>;
- fn map_loop(self, f: F) -> Self::Return where E: EmptyType;
-
- type TryReturn: Iterator<Item=Result<U,E>>;
- fn try_map_loop(self, f: F) -> Self::TryReturn;
-}
-
pub trait EmptyType { fn diverge<T>(self) -> T; }
impl EmptyType for Infallible {
fn diverge<T>(self) -> T { match self { } }
}
-impl<T,U,E,F> IteratorExt<U,E,F> for T where
- T: Iterator,
- F: FnMut(Self::Item) -> Result<U,Loop<E>>,
-{
- type Return = impl Iterator<Item=U>;
- fn map_loop(self, f: F) -> Self::Return 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())
- }
-
- type TryReturn = impl Iterator<Item=Result<U,E>>;
- fn try_map_loop(self, f: F) -> Self::TryReturn {
- 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!(),
- })
- }
-}
-
#[macro_export] // <- otherwise bogus warning `unused_macros`
macro_rules! matches_doesnot_yn2bool {
(=) => (true);