| #[macro_use] |
| extern crate derive_builder; |
| |
| #[derive(Debug, Clone, Builder, PartialEq, Eq)] |
| #[builder(build_fn(validate = "LoremBuilder::validate"))] |
| pub struct Lorem { |
| /// A percentile. Must be between 0 and 100. |
| my_effort: u8, |
| |
| /// A percentile. Must be less than or equal to `Lorem::my_effort`. |
| #[builder(default = "40")] |
| their_effort: u8, |
| |
| /// A percentile. Must be between 0 and 100. |
| rivals_effort: u8, |
| } |
| |
| impl LoremBuilder { |
| /// Performs bound checks. |
| fn validate(&self) -> Result<(), String> { |
| if let Some(ref my_effort) = self.my_effort { |
| if *my_effort > 100 { |
| return Err("Don't wear yourself out".to_string()); |
| } |
| } |
| |
| if let Some(ref their_effort) = self.their_effort { |
| if *their_effort > 100 { |
| return Err("The game has changed".to_string()); |
| } |
| } |
| |
| if let Some(ref rivals_effort) = self.rivals_effort { |
| if *rivals_effort > 100 { |
| return Err("Your rival is cheating".to_string()); |
| } |
| } |
| |
| Ok(()) |
| } |
| } |
| |
| #[test] |
| fn out_of_bounds() { |
| assert_eq!( |
| &LoremBuilder::default() |
| .my_effort(120) |
| .build() |
| .unwrap_err() |
| .to_string(), |
| "Don't wear yourself out" |
| ); |
| assert_eq!( |
| &LoremBuilder::default() |
| .rivals_effort(120) |
| .build() |
| .unwrap_err() |
| .to_string(), |
| "Your rival is cheating" |
| ); |
| } |
| |
| #[test] |
| fn validation_pass() { |
| let lorem = LoremBuilder::default() |
| .my_effort(90) |
| .rivals_effort(89) |
| .build() |
| .expect("All validations should be passing"); |
| |
| assert_eq!( |
| lorem, |
| Lorem { |
| my_effort: 90, |
| rivals_effort: 89, |
| their_effort: 40, |
| } |
| ); |
| } |