Skip to content

Instantly share code, notes, and snippets.

@matklad

matklad/ii.rs Secret

Created June 25, 2019 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matklad/8c3a413f5e2cc144eeb0da2dc761abd7 to your computer and use it in GitHub Desktop.
Save matklad/8c3a413f5e2cc144eeb0da2dc761abd7 to your computer and use it in GitHub Desktop.
use std::iter;
pub trait Iterator: Sized {
type Item;
fn extend_into<E: iter::Extend<Self::Item>>(self, acc: &mut E);
fn find_map<B, F>(self, f: F) -> Option<B>
where
F: FnMut(Self::Item) -> Option<B>,
{
struct FindMap<T, F> {
res: Option<T>,
f: F,
}
impl<I, T, F: FnMut(I) -> Option<T>> Extend<I> for FindMap<T, F> {
fn extend<ITER: IntoIterator<Item = I>>(&mut self, iter: ITER) {
iter.into_iter().try_for_each(|item| match (self.f)(item) {
Some(res) => {
self.res = Some(res);
Err(())
}
None => Ok(()),
});
}
}
let mut fm = FindMap { res: None, f };
self.extend_into(&mut fm);
fm.res
}
}
pub fn from_fn<F>(f: F) -> FromFn<F> {
FromFn { f }
}
pub struct FromFn<F> {
f: F,
}
impl<T, F> Iterator for FromFn<F>
where F: for<E: iter::Extend<T>> FnMut(&mut E)
{
fn extend_into<E: iter::Extend<Self::Item>>(self, acc: &mut E) {
(self.f)(acc)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment