use thiserror::Error;
#[derive(Debug)]
pub struct Matcher {
number: usize,
word: String,
}
impl Matcher {
pub fn new(number: usize, word: &str) -> Result<Self, MatcherError> {
if number == 0 {
return Err(MatcherError::NumberIsZero);
}
Ok(Matcher {
number: number,
word: word.to_owned(),
})
}
pub fn matches(self: &Self, number: usize) -> bool {
number % self.number == 0
}
pub fn text(self: &Self, number: usize) -> &str {
if self.matches(number) {
return &self.word;
}
""
}
}
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum MatcherError {
#[error("`number` is 0, but division by 0 is impossible")]
NumberIsZero,
}
#[cfg(test)]
mod tests {
use super::*;
use rand::random;
#[test]
fn new_normal() {
let word = "Test";
let mut number = 0;
while number == 0 {
number = random();
}
let matcher = Matcher::new(number, word).unwrap();
assert_eq!(matcher.number, number);
assert_eq!(matcher.word, word.to_string());
}
#[test]
fn new_zero() -> Result<(), String> {
let word = "Test";
let number = 0;
let matcher_res = Matcher::new(number, word);
match matcher_res {
Err(e) => match e {
MatcherError::NumberIsZero => Ok(()),
_ => Err("Wrong error kind".to_string()),
},
_ => Err("Wrongfully succeeded".to_string()),
}
}
#[test]
fn matches_normal() {
let word = "Test";
let mut number = 0;
while number == 0 || number == 1 {
number = random();
}
let matcher = Matcher::new(number, word).unwrap();
assert!(!matcher.matches(number - 1));
assert!(matcher.matches(number));
assert!(!matcher.matches(number + 1));
}
#[test]
fn matches_one() {
let word = "Test";
let number = 1;
let matcher = Matcher::new(number, word).unwrap();
assert!(matcher.matches(number - 1));
assert!(matcher.matches(number));
assert!(matcher.matches(number + 1));
}
#[test]
fn text_normal() {
let word = "Test";
let mut number = 0;
while number == 0 || number == 1 {
number = random();
}
let matcher = Matcher::new(number, word).unwrap();
assert_eq!(matcher.text(number - 1), "");
assert_eq!(matcher.text(number), word);
assert_eq!(matcher.text(number + 1), "");
}
#[test]
fn text_one() {
let word = "Test";
let number = 1;
let matcher = Matcher::new(number, word).unwrap();
assert_eq!(matcher.text(number - 1), word);
assert_eq!(matcher.text(number), word);
assert_eq!(matcher.text(number + 1), word);
}
}