diff --git a/src/counter.rs b/src/counter.rs index 2c81185..f32c83e 100644 --- a/src/counter.rs +++ b/src/counter.rs @@ -4,7 +4,7 @@ use actix::prelude::*; use derive_builder::Builder; //use lazy_static::*; -use crate::new_levels::Defense; +use crate::levels::Defense; //use crate::new_levels::Levels; // TODO move this into config parameter @@ -97,7 +97,7 @@ impl Handler for Counter { #[cfg(test)] mod tests { use super::*; - use crate::new_levels::*; + use crate::levels::*; // constants foor testing // (visitor count, level) diff --git a/src/levels.rs b/src/levels.rs index 64b5a55..bf4869c 100644 --- a/src/levels.rs +++ b/src/levels.rs @@ -1,88 +1,206 @@ +// //! ```rust +// //! DefenseBuilder::default() +// //! .add_level( +// //! LevelBuilder::default() +// //! .visitor_count(50) +// //! .difficulty_factor(50) +// //! .unwrap() +// //! .build() +// //! .unwrap(), +// //! ) +// //! .unwrap() +// //! .add_level( +// //! LevelBuilder::default() +// //! .visitor_count(500) +// //! .difficulty_factor(500) +// //! .unwrap() +// //! .build() +// //! .unwrap(), +// //! ) +// //! .unwrap() +// //! .build() +// //! .unwrap(); +// //! ``` + +use crate::errors::*; + +/// Level struct #[derive(Debug, Copy, Clone, PartialEq)] -pub enum Levels { - One = 500, - Two = 1000, - Three = 2000, - Four = 4000, +pub struct Level { + visitor_count: u32, + difficulty_factor: u32, } -impl Default for Levels { +impl Default for Level { fn default() -> Self { - Levels::One + Level { + visitor_count: 0, + difficulty_factor: 0, + } } } -impl Levels { - pub fn relax(&mut self) -> u32 { - self.rev().next(); - *self as u32 +/// set difficulty configuration +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct LevelBuilder { + visitor_count: Option, + difficulty_factor: Option, +} + +impl Default for LevelBuilder { + fn default() -> Self { + LevelBuilder { + visitor_count: None, + difficulty_factor: None, + } + } +} + +impl LevelBuilder { + /// set visitor count for level + pub fn visitor_count(&mut self, visitor_count: u32) -> &mut Self { + self.visitor_count = Some(visitor_count); + self } + /// set difficulty factor for level + /// difficulty_factor can't be zero because + /// Difficulty is calculated as + /// ```no_run + /// let difficulty_factor = 500; + /// let difficulty = u128::max_value() - u128::max_value() / difficulty_factor; + /// ``` + /// the higher the `difficulty_factor`, the higher the difficulty. + pub fn difficulty_factor(&mut self, difficulty_factor: u32) -> CaptchaResult<&mut Self> { + if difficulty_factor > 0 { + self.difficulty_factor = Some(difficulty_factor); + Ok(self) + } else { + Err(CaptchaError::DifficultyFactorZero) + } + } + + /// build Level + pub fn build(&mut self) -> CaptchaResult { + if self.visitor_count.is_none() { + Err(CaptchaError::SetVisitorCount) + } else if self.difficulty_factor.is_none() { + Err(CaptchaError::SetDifficultyFactor) + } else { + Ok(Level { + difficulty_factor: self.difficulty_factor.unwrap(), + visitor_count: self.visitor_count.unwrap(), + }) + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct Defense { + levels: Vec, + // index of current visitor threshold + current_visitor_threshold: usize, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct DefenseBuilder { + levels: Vec, +} + +impl Default for DefenseBuilder { + fn default() -> Self { + DefenseBuilder { levels: vec![] } + } +} + +impl DefenseBuilder { + pub fn add_level(&mut self, level: Level) -> CaptchaResult<&mut Self> { + for i in self.levels.iter() { + if i.visitor_count == level.visitor_count { + return Err(CaptchaError::DuplicateVisitorCount); + } + } + self.levels.push(level); + Ok(self) + } + + pub fn build(&mut self) -> CaptchaResult { + if !self.levels.is_empty() { + // sort levels to arrange in ascending order + self.levels.sort_by_key(|a| a.visitor_count); + + // as visitor count increases, difficulty_factor too should increse + + for level in self.levels.iter() { + if level.difficulty_factor == 0 { + return Err(CaptchaError::DifficultyFactorZero); + } + } + + for i in 0..self.levels.len() - 1 { + if self.levels[i].difficulty_factor > self.levels[i + 1].difficulty_factor { + return Err(CaptchaError::DecreaseingDifficultyFactor); + } + } + + Ok(Defense { + levels: self.levels.to_owned(), + current_visitor_threshold: 0, + }) + } else { + Err(CaptchaError::LevelEmpty) + } + } +} + +impl Default for Defense { + fn default() -> Self { + Defense { + levels: vec![Level::default()], + current_visitor_threshold: 0, + } + } +} + +impl Defense { ///! Difficulty is calculated as ///! ```rust ///! let difficulty = u128::max_value() - u128::max_value() / difficulty_factor; ///! ``` ///! the higher the `difficulty_factor`, the higher the difficulty. + /// get difficulty factor of current level of defense pub fn get_difficulty(&self) -> u32 { - match self { - Levels::Three => 100_000, - Levels::Four => 1_000_000, - _ => *self as u32, + self.levels[self.current_visitor_threshold].difficulty_factor + } + + /// tighten up defense. Increases defense level by a factor of one + /// when defense is at max level, calling this method will have no effect + pub fn tighten_up(&mut self) { + if self.current_visitor_threshold != self.levels.len() - 1 { + self.current_visitor_threshold += 1; + } + } + /// loosen up defense. Decreases defense level by a factor of one + /// when defense is at the lowest level, calling this method will have no effect + pub fn loosen_up(&mut self) { + if self.current_visitor_threshold != 0 { + self.current_visitor_threshold -= 1; } } - pub fn threshold(&self) -> usize { - *self as usize + /// set defense to maximum level + pub fn max_defense(&mut self) { + self.current_visitor_threshold = self.levels.len() - 1; } - pub fn focus(&mut self) -> u32 { - self.next(); - *self as u32 + /// set defense to minimum level + pub fn min_defense(&mut self) { + self.current_visitor_threshold = 0; } -} -impl DoubleEndedIterator for Levels { - fn next_back(&mut self) -> Option { - match self { - Levels::One => { - *self = Levels::One; - } - Levels::Two => { - *self = Levels::One; - } - Levels::Three => { - *self = Levels::Two; - } - Levels::Four => { - *self = Levels::Three; - } - }; - - Some(()) - } -} - -impl Iterator for Levels { - type Item = (); - - fn next(&mut self) -> Option<()> { - match self { - Levels::One => { - *self = Levels::Two; - } - Levels::Two => { - *self = Levels::Three; - } - Levels::Three => { - *self = Levels::Four; - } - Levels::Four => { - *self = Levels::Four; - } - }; - - Some(()) + pub fn visitor_threshold(&self) -> u32 { + self.levels[self.current_visitor_threshold].visitor_count } } @@ -91,72 +209,214 @@ mod tests { use super::*; #[test] - fn levels_enum_works() { - let mut level = Levels::default(); + fn level_builder_works() { + let level = LevelBuilder::default() + .difficulty_factor(1) + .unwrap() + .visitor_count(0) + .build() + .unwrap(); - assert_eq!(level, Levels::One); + assert_eq!(level.visitor_count, 0); + assert_eq!(level.difficulty_factor, 1); - level.next(); - assert_eq!(level, Levels::Two); - - level.next(); - assert_eq!(level, Levels::Three); - - level.next(); - assert_eq!(level, Levels::Four); - - level.next(); - assert_eq!(level, Levels::Four); + assert_eq!( + LevelBuilder::default().difficulty_factor(0), + Err(CaptchaError::DifficultyFactorZero) + ); } #[test] - fn focus_works() { - let mut level = Levels::default(); - - assert_eq!(level, Levels::One); - assert_eq!(level.focus(), Levels::Two as u32); - assert_eq!(level.focus(), Levels::Three as u32); - assert_eq!(level.focus(), Levels::Four as u32); - assert_eq!(level.focus(), Levels::Four as u32); + fn defense_builder_duplicate_visitor_count() { + let mut defense_builder = DefenseBuilder::default(); + let err = defense_builder + .add_level( + LevelBuilder::default() + .visitor_count(50) + .difficulty_factor(50) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .add_level( + LevelBuilder::default() + .visitor_count(50) + .difficulty_factor(50) + .unwrap() + .build() + .unwrap(), + ); + assert_eq!(err, Err(CaptchaError::DuplicateVisitorCount)); } #[test] - fn relax_works() { - let mut level = Levels::default(); + fn defense_builder_decreasing_difficulty_factor() { + let mut defense_builder = DefenseBuilder::default(); + let err = defense_builder + .add_level( + LevelBuilder::default() + .visitor_count(50) + .difficulty_factor(50) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .add_level( + LevelBuilder::default() + .visitor_count(500) + .difficulty_factor(10) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .build(); + assert_eq!(err, Err(CaptchaError::DecreaseingDifficultyFactor)); + } - assert_eq!(level, Levels::One); - assert_eq!(level.focus(), Levels::Two as u32); - assert_eq!(level.focus(), Levels::Three as u32); - assert_eq!(level.focus(), Levels::Four as u32); + fn get_defense() -> Defense { + DefenseBuilder::default() + .add_level( + LevelBuilder::default() + .visitor_count(50) + .difficulty_factor(50) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .add_level( + LevelBuilder::default() + .visitor_count(500) + .difficulty_factor(5000) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .add_level( + LevelBuilder::default() + .visitor_count(5000) + .difficulty_factor(50000) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .add_level( + LevelBuilder::default() + .visitor_count(50000) + .difficulty_factor(500000) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .add_level( + LevelBuilder::default() + .visitor_count(500000) + .difficulty_factor(5000000) + .unwrap() + .build() + .unwrap(), + ) + .unwrap() + .build() + .unwrap() + } + #[test] + fn defense_builder_works() { + let defense = get_defense(); - assert_eq!(level.relax(), Levels::Three as u32); - assert_eq!(level.relax(), Levels::Two as u32); - - assert_eq!(level.relax(), Levels::One as u32); - assert_eq!(level.relax(), Levels::One as u32); + assert_eq!(defense.levels[0].difficulty_factor, 50); + assert_eq!(defense.levels[1].difficulty_factor, 5000); + assert_eq!(defense.levels[2].difficulty_factor, 50_000); + assert_eq!(defense.levels[3].difficulty_factor, 500_000); + assert_eq!(defense.levels[4].difficulty_factor, 5_000_000); } #[test] - fn threshold_works() { - let mut level = Levels::default(); + fn tighten_up_works() { + let mut defense = get_defense(); - assert_eq!(level.threshold(), Levels::One as usize); - level.next(); - assert_eq!(level.threshold(), Levels::Two as usize); - level.next(); - assert_eq!(level.threshold(), Levels::Three as usize); + assert_eq!(defense.get_difficulty(), 50); + + defense.tighten_up(); + assert_eq!(defense.get_difficulty(), 5_000); + + defense.tighten_up(); + assert_eq!(defense.get_difficulty(), 50_000); + + defense.tighten_up(); + assert_eq!(defense.get_difficulty(), 500_000); + + defense.tighten_up(); + assert_eq!(defense.get_difficulty(), 5_000_000); + + defense.tighten_up(); + assert_eq!(defense.get_difficulty(), 5_000_000); } #[test] - fn difficulty_works() { - let mut level = Levels::default(); - - assert_eq!(level.get_difficulty(), Levels::One as u32); - level.next(); - assert_eq!(level.get_difficulty(), Levels::Two as u32); - level.next(); - assert_eq!(level.get_difficulty(), 100_000); - level.next(); - assert_eq!(level.get_difficulty(), 1_000_000); + fn max_defense_works() { + let mut defense = get_defense(); + defense.max_defense(); + assert_eq!(defense.get_difficulty(), 5_000_000); } + + #[test] + fn minimum_defense_works() { + let mut defense = get_defense(); + defense.min_defense(); + assert_eq!(defense.get_difficulty(), 50); + } + + #[test] + fn loosen_up_works() { + let mut defense = get_defense(); + defense.max_defense(); + + assert_eq!(defense.get_difficulty(), 5_000_000); + + defense.loosen_up(); + assert_eq!(defense.get_difficulty(), 500_000); + + defense.loosen_up(); + assert_eq!(defense.get_difficulty(), 50_000); + + defense.loosen_up(); + assert_eq!(defense.get_difficulty(), 5_000); + + defense.loosen_up(); + assert_eq!(defense.get_difficulty(), 50); + + defense.loosen_up(); + assert_eq!(defense.get_difficulty(), 50); + } + + // #[test] + // fn threshold_works() { + // let mut level = Levels::default(); + // + // assert_eq!(level.threshold(), Levels::One as usize); + // level.next(); + // assert_eq!(level.threshold(), Levels::Two as usize); + // level.next(); + // assert_eq!(level.threshold(), Levels::Three as usize); + // } + // + // #[test] + // fn difficulty_works() { + // let mut level = Levels::default(); + // + // assert_eq!(level.get_difficulty(), Levels::One as u32); + // level.next(); + // assert_eq!(level.get_difficulty(), Levels::Two as u32); + // level.next(); + // assert_eq!(level.get_difficulty(), 100_000); + // level.next(); + // assert_eq!(level.get_difficulty(), 1_000_000); + // } } diff --git a/src/lib.rs b/src/lib.rs index cf75f9c..350d9c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ pub mod counter; pub mod errors; -mod levels; -pub mod new_levels; +pub mod levels; diff --git a/src/new_levels.rs b/src/new_levels.rs deleted file mode 100644 index bf4869c..0000000 --- a/src/new_levels.rs +++ /dev/null @@ -1,422 +0,0 @@ -// //! ```rust -// //! DefenseBuilder::default() -// //! .add_level( -// //! LevelBuilder::default() -// //! .visitor_count(50) -// //! .difficulty_factor(50) -// //! .unwrap() -// //! .build() -// //! .unwrap(), -// //! ) -// //! .unwrap() -// //! .add_level( -// //! LevelBuilder::default() -// //! .visitor_count(500) -// //! .difficulty_factor(500) -// //! .unwrap() -// //! .build() -// //! .unwrap(), -// //! ) -// //! .unwrap() -// //! .build() -// //! .unwrap(); -// //! ``` - -use crate::errors::*; - -/// Level struct -#[derive(Debug, Copy, Clone, PartialEq)] -pub struct Level { - visitor_count: u32, - difficulty_factor: u32, -} - -impl Default for Level { - fn default() -> Self { - Level { - visitor_count: 0, - difficulty_factor: 0, - } - } -} - -/// set difficulty configuration -#[derive(Debug, Copy, Clone, PartialEq)] -pub struct LevelBuilder { - visitor_count: Option, - difficulty_factor: Option, -} - -impl Default for LevelBuilder { - fn default() -> Self { - LevelBuilder { - visitor_count: None, - difficulty_factor: None, - } - } -} - -impl LevelBuilder { - /// set visitor count for level - pub fn visitor_count(&mut self, visitor_count: u32) -> &mut Self { - self.visitor_count = Some(visitor_count); - self - } - - /// set difficulty factor for level - /// difficulty_factor can't be zero because - /// Difficulty is calculated as - /// ```no_run - /// let difficulty_factor = 500; - /// let difficulty = u128::max_value() - u128::max_value() / difficulty_factor; - /// ``` - /// the higher the `difficulty_factor`, the higher the difficulty. - pub fn difficulty_factor(&mut self, difficulty_factor: u32) -> CaptchaResult<&mut Self> { - if difficulty_factor > 0 { - self.difficulty_factor = Some(difficulty_factor); - Ok(self) - } else { - Err(CaptchaError::DifficultyFactorZero) - } - } - - /// build Level - pub fn build(&mut self) -> CaptchaResult { - if self.visitor_count.is_none() { - Err(CaptchaError::SetVisitorCount) - } else if self.difficulty_factor.is_none() { - Err(CaptchaError::SetDifficultyFactor) - } else { - Ok(Level { - difficulty_factor: self.difficulty_factor.unwrap(), - visitor_count: self.visitor_count.unwrap(), - }) - } - } -} - -#[derive(Debug, Clone, PartialEq)] -pub struct Defense { - levels: Vec, - // index of current visitor threshold - current_visitor_threshold: usize, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct DefenseBuilder { - levels: Vec, -} - -impl Default for DefenseBuilder { - fn default() -> Self { - DefenseBuilder { levels: vec![] } - } -} - -impl DefenseBuilder { - pub fn add_level(&mut self, level: Level) -> CaptchaResult<&mut Self> { - for i in self.levels.iter() { - if i.visitor_count == level.visitor_count { - return Err(CaptchaError::DuplicateVisitorCount); - } - } - self.levels.push(level); - Ok(self) - } - - pub fn build(&mut self) -> CaptchaResult { - if !self.levels.is_empty() { - // sort levels to arrange in ascending order - self.levels.sort_by_key(|a| a.visitor_count); - - // as visitor count increases, difficulty_factor too should increse - - for level in self.levels.iter() { - if level.difficulty_factor == 0 { - return Err(CaptchaError::DifficultyFactorZero); - } - } - - for i in 0..self.levels.len() - 1 { - if self.levels[i].difficulty_factor > self.levels[i + 1].difficulty_factor { - return Err(CaptchaError::DecreaseingDifficultyFactor); - } - } - - Ok(Defense { - levels: self.levels.to_owned(), - current_visitor_threshold: 0, - }) - } else { - Err(CaptchaError::LevelEmpty) - } - } -} - -impl Default for Defense { - fn default() -> Self { - Defense { - levels: vec![Level::default()], - current_visitor_threshold: 0, - } - } -} - -impl Defense { - ///! Difficulty is calculated as - ///! ```rust - ///! let difficulty = u128::max_value() - u128::max_value() / difficulty_factor; - ///! ``` - ///! the higher the `difficulty_factor`, the higher the difficulty. - - /// get difficulty factor of current level of defense - pub fn get_difficulty(&self) -> u32 { - self.levels[self.current_visitor_threshold].difficulty_factor - } - - /// tighten up defense. Increases defense level by a factor of one - /// when defense is at max level, calling this method will have no effect - pub fn tighten_up(&mut self) { - if self.current_visitor_threshold != self.levels.len() - 1 { - self.current_visitor_threshold += 1; - } - } - /// loosen up defense. Decreases defense level by a factor of one - /// when defense is at the lowest level, calling this method will have no effect - pub fn loosen_up(&mut self) { - if self.current_visitor_threshold != 0 { - self.current_visitor_threshold -= 1; - } - } - - /// set defense to maximum level - pub fn max_defense(&mut self) { - self.current_visitor_threshold = self.levels.len() - 1; - } - - /// set defense to minimum level - pub fn min_defense(&mut self) { - self.current_visitor_threshold = 0; - } - - pub fn visitor_threshold(&self) -> u32 { - self.levels[self.current_visitor_threshold].visitor_count - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn level_builder_works() { - let level = LevelBuilder::default() - .difficulty_factor(1) - .unwrap() - .visitor_count(0) - .build() - .unwrap(); - - assert_eq!(level.visitor_count, 0); - assert_eq!(level.difficulty_factor, 1); - - assert_eq!( - LevelBuilder::default().difficulty_factor(0), - Err(CaptchaError::DifficultyFactorZero) - ); - } - - #[test] - fn defense_builder_duplicate_visitor_count() { - let mut defense_builder = DefenseBuilder::default(); - let err = defense_builder - .add_level( - LevelBuilder::default() - .visitor_count(50) - .difficulty_factor(50) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .add_level( - LevelBuilder::default() - .visitor_count(50) - .difficulty_factor(50) - .unwrap() - .build() - .unwrap(), - ); - assert_eq!(err, Err(CaptchaError::DuplicateVisitorCount)); - } - - #[test] - fn defense_builder_decreasing_difficulty_factor() { - let mut defense_builder = DefenseBuilder::default(); - let err = defense_builder - .add_level( - LevelBuilder::default() - .visitor_count(50) - .difficulty_factor(50) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .add_level( - LevelBuilder::default() - .visitor_count(500) - .difficulty_factor(10) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .build(); - assert_eq!(err, Err(CaptchaError::DecreaseingDifficultyFactor)); - } - - fn get_defense() -> Defense { - DefenseBuilder::default() - .add_level( - LevelBuilder::default() - .visitor_count(50) - .difficulty_factor(50) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .add_level( - LevelBuilder::default() - .visitor_count(500) - .difficulty_factor(5000) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .add_level( - LevelBuilder::default() - .visitor_count(5000) - .difficulty_factor(50000) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .add_level( - LevelBuilder::default() - .visitor_count(50000) - .difficulty_factor(500000) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .add_level( - LevelBuilder::default() - .visitor_count(500000) - .difficulty_factor(5000000) - .unwrap() - .build() - .unwrap(), - ) - .unwrap() - .build() - .unwrap() - } - #[test] - fn defense_builder_works() { - let defense = get_defense(); - - assert_eq!(defense.levels[0].difficulty_factor, 50); - assert_eq!(defense.levels[1].difficulty_factor, 5000); - assert_eq!(defense.levels[2].difficulty_factor, 50_000); - assert_eq!(defense.levels[3].difficulty_factor, 500_000); - assert_eq!(defense.levels[4].difficulty_factor, 5_000_000); - } - - #[test] - fn tighten_up_works() { - let mut defense = get_defense(); - - assert_eq!(defense.get_difficulty(), 50); - - defense.tighten_up(); - assert_eq!(defense.get_difficulty(), 5_000); - - defense.tighten_up(); - assert_eq!(defense.get_difficulty(), 50_000); - - defense.tighten_up(); - assert_eq!(defense.get_difficulty(), 500_000); - - defense.tighten_up(); - assert_eq!(defense.get_difficulty(), 5_000_000); - - defense.tighten_up(); - assert_eq!(defense.get_difficulty(), 5_000_000); - } - - #[test] - fn max_defense_works() { - let mut defense = get_defense(); - defense.max_defense(); - assert_eq!(defense.get_difficulty(), 5_000_000); - } - - #[test] - fn minimum_defense_works() { - let mut defense = get_defense(); - defense.min_defense(); - assert_eq!(defense.get_difficulty(), 50); - } - - #[test] - fn loosen_up_works() { - let mut defense = get_defense(); - defense.max_defense(); - - assert_eq!(defense.get_difficulty(), 5_000_000); - - defense.loosen_up(); - assert_eq!(defense.get_difficulty(), 500_000); - - defense.loosen_up(); - assert_eq!(defense.get_difficulty(), 50_000); - - defense.loosen_up(); - assert_eq!(defense.get_difficulty(), 5_000); - - defense.loosen_up(); - assert_eq!(defense.get_difficulty(), 50); - - defense.loosen_up(); - assert_eq!(defense.get_difficulty(), 50); - } - - // #[test] - // fn threshold_works() { - // let mut level = Levels::default(); - // - // assert_eq!(level.threshold(), Levels::One as usize); - // level.next(); - // assert_eq!(level.threshold(), Levels::Two as usize); - // level.next(); - // assert_eq!(level.threshold(), Levels::Three as usize); - // } - // - // #[test] - // fn difficulty_works() { - // let mut level = Levels::default(); - // - // assert_eq!(level.get_difficulty(), Levels::One as u32); - // level.next(); - // assert_eq!(level.get_difficulty(), Levels::Two as u32); - // level.next(); - // assert_eq!(level.get_difficulty(), 100_000); - // level.next(); - // assert_eq!(level.get_difficulty(), 1_000_000); - // } -}