Skip to content

Instantly share code, notes, and snippets.

@iTrooz
Created February 22, 2024 22:34
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 iTrooz/60c4b8f04c854b5155c63c4026be48b1 to your computer and use it in GitHub Desktop.
Save iTrooz/60c4b8f04c854b5155c63c4026be48b1 to your computer and use it in GitHub Desktop.
// can be replace by std::iter::from_fn(): https://doc.rust-lang.org/std/iter/fn.from_fn.html
struct EitherIterator<A, B, C>
where
A: Iterator<Item = C>,
B: Iterator<Item = C>,
{
either: itertools::Either<A, B>,
}
impl<A, B, C> Iterator for EitherIterator<A, B, C>
where
A: Iterator<Item = C>,
B: Iterator<Item = C>,
{
type Item = C;
fn next(&mut self) -> Option<Self::Item> {
match &mut self.either {
Either::Left(ref mut left) => left.next(),
Either::Right(ref mut right) => right.next(),
}
}
}
// usage
fn get_inbetween_points(
p1: &(isize, isize),
p2: &(isize, isize),
) -> impl Iterator<Item = (isize, isize)> {
let xdiff = p2.0 - p1.0;
let it: EitherIterator<_, _, (isize, isize)>;
if xdiff == 0 {
let y_range = (p1.1.min(p2.1) + 1)..p1.1.max(p2.1);
let p1x = p1.0;
let fun = y_range.filter_map(move |y| Some((p1x, y)));
it = EitherIterator {
either: Either::Left(fun),
}
} else {
let slope = (p2.1 - p1.1) as f64 / xdiff as f64;
let init = p2.1 as f64 - slope * p2.0 as f64;
let x_range = (p1.0.min(p2.0) + 1)..p1.0.max(p2.0);
let fun = x_range.filter_map(move |x| {
let y = slope * x as f64 + init;
if is_close_int(y) {
Some((x, y.round() as isize))
} else {
None
}
});
it = EitherIterator {
either: Either::Right(fun),
}
}
it
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment