Skip to content

Instantly share code, notes, and snippets.

@carrascomj
Created December 30, 2021 15:40
Show Gist options
  • Save carrascomj/9720111916f1fec36866741c8c21ffe6 to your computer and use it in GitHub Desktop.
Save carrascomj/9720111916f1fec36866741c8c21ffe6 to your computer and use it in GitHub Desktop.
Rust FizzBuzz Iterator
#[derive(Debug, PartialEq, PartialOrd)]
pub enum FizzBuzz<T> {
Fizz,
Buzz,
FizzBuzz,
Value(T),
}
#[must_use = "iterators are lazy and must be consumed"]
pub struct FBIt<I> {
iter: I,
count: usize,
}
impl<I> FBIt<I> {
fn new(iter: I) -> Self {
Self { iter, count: 0 }
}
}
impl<I> Iterator for FBIt<I>
where
I: Iterator,
{
type Item = FizzBuzz<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
let res = self.iter.next().map(|arg| {
if self.count % 15 == 0 {
FizzBuzz::FizzBuzz
} else if self.count % 3 == 0 {
FizzBuzz::Fizz
} else if self.count % 5 == 0 {
FizzBuzz::Buzz
} else {
FizzBuzz::Value(arg)
}
});
self.count += 1;
res
}
}
pub trait IntoFizzIterator<I> {
fn fizz(self) -> FBIt<I>;
}
impl<I> IntoFizzIterator<I> for I
where
I: Iterator,
{
fn fizz(self) -> FBIt<I> {
FBIt::new(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
// testing can also be overengineered
impl FizzBuzz<i32> {
pub fn number(i: usize) -> FizzBuzz<i32> {
match i {
15 => FizzBuzz::FizzBuzz,
3 => FizzBuzz::Fizz,
5 => FizzBuzz::Buzz,
_ => FizzBuzz::Value(0),
}
}
}
#[test]
fn get_fizz_buzz_constructs() {
assert!(FBIt::new(1i32..100i32)
.enumerate()
.filter(|(i, _)| i % 15 == 0)
.all(|(_, x)| x == FizzBuzz::FizzBuzz))
}
#[test]
fn get_fizz_buzz_flows_from_iter() {
assert!((1i32..100i32)
.fizz()
.enumerate()
.filter(|(i, _)| i % 15 == 0)
.all(|(_, x)| x == FizzBuzz::FizzBuzz))
}
#[test]
fn all_fizz_cases_are_satisfied() {
for count in [3, 5, 15] {
assert!((1i32..100i32)
.fizz()
.enumerate()
// count case except when count != 15 and i is a 15 multiple
.filter(|(i, _)| (i % count == 0) & ((i % 15 != 0) & (count != 15)))
.all(|(_, x)| x == FizzBuzz::number(count)))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment