Rust is one of my first forays on a strongly typed language, beginning to like it's strictness, and am looking to improve my comprehension.
Rules
Fizzbuzz is a programming challenge with the following rules for output;
n
mod3
=>"Fizz"
n
mod5
=>"Buzz"
n
mod3
&&n
mod5
=>"Fizzbuzz"
else
n
=>n
Examples;
10
=>"Buzz"
11
=>"11"
12
=>"Fizz"
13
=>"13"
14
=>"14"
15
=>"Fizzbuzz"
Questions
Are there any mistakes that the compiler hasn't pestered my about?
The iterator increments or decrements, any other directions it should go?
It's not the shortest implementation, not my primary goal, but do any bits of code smell?
What other features would be good to add for the learning experience?
Steps to Reproduce
Initialization
cargo init fizzbuzz
cd fizzbuzz
Add argparse
as dependency to Cargo.toml
file
[dependencies]
argparse = "0.2.2"
See
Source Code
for contents ofsrc/main.rs
file.
Compiling and running
cargo build
./target/debug/fizzbuzz --begin 1 --end 26
./target/debug/fizzbuzz --begin 100 --end 74
Source Code
src/main.rs
extern crate argparse;
use argparse::{ArgumentParser, Store, StoreTrue};
/// **Licensing**
///
/// Rust Fizzbuzz
/// Copyright (C) 2020 S0AndS0
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation; version 3 of the License.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
/// Data structure for mutable states within `Game`
#[derive(Clone)]
struct State {
fizz: bool,
buzz: bool,
count: u32,
message: String
}
impl State {
/// Method for defaulting values other than `count`
fn new(count: Option<u32>) -> Self {
let count: u32 = match count {
Some(i) => { i },
None => { 1 }
};
return State {
fizz: false,
buzz: false,
count: count,
message: String::from(""),
}
}
}
/// Data structure of what `Game` is concerned with
struct Game {
state: State,
limit: u32,
}
impl Game {
/// Method for initializing game with counter and limit
fn new(count: Option<u32>, limit: Option<u32>) -> Self {
let limit: u32 = match limit {
Some(i) => { i },
None => { 16 }
};
Game { state: State::new(count), limit: limit }
}
}
impl Iterator for Game {
/// Return type of iterator
type Item = State;
/// Called implicitly by `for` loops
fn next(&mut self) -> Option<State> {
self.state.fizz = false;
self.state.buzz = false;
self.state.message = String::from("");
if self.state.count % 3 == 0 {
self.state.fizz = true;
self.state.message.push_str("fizz");
}
if self.state.count % 5 == 0 {
self.state.buzz = true;
self.state.message.push_str("buzz");
}
if self.state.message.is_empty() {
self.state.message = self.state.count.to_string();
} else if let Some(r) = self.state.message.get_mut(0..1) {
r.make_ascii_uppercase();
}
if self.state.count != self.limit {
if self.state.count < self.limit {
self.state.count += 1;
} else {
self.state.count -= 1;
}
Some(self.state.clone())
} else {
None
}
}
}
/// Called automatically by `cargo run` command or executing compiled binary
fn main() {
let mut begin: u32 = 1;
let mut end: u32 = 100;
let mut verbose = false;
// Limit borrowing scope for `ap.refer` methods.
{
let mut ap = ArgumentParser::new();
ap.set_description("Iterator based Fizzbuzz example writen in Rust");
ap.refer(&mut begin).add_option(
&["--begin", "--start"],
Store,
"Where iteration begins"
);
ap.refer(&mut end).add_option(
&["--end", "--stop"],
Store,
"Where iteration ends"
);
ap.refer(&mut verbose).add_option(
&["-v", "--verbose"],
StoreTrue,
"How _noisy_ to be"
);
ap.parse_args_or_exit();
}
if verbose {
println!("begin -> {}", begin);
println!("end -> {}", end);
}
let game: Game = Game::new(Some(begin), Some(end));
for state in game {
println!("{}", state.message);
}
}