diff --git a/Cargo.lock b/Cargo.lock index fb46a6c..2706aa5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,4 +4,4 @@ version = 3 [[package]] name = "electosim" -version = "0.2.2" +version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index bd471d1..33e038a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "electosim" -version = "0.2.2" +version = "0.2.3" edition = "2021" authors = ["Eduardo González Vaquero "] description = "Library to compute electoral methods (as D'Hondt) and simulate elections" diff --git a/src/interface.rs b/src/interface.rs index 44cffee..cb7e83d 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -5,6 +5,16 @@ pub trait WithVotes { /// Sets the number of votes. fn set_votes(&mut self, votes: u32); + + /// Increases the number of votes by a given amount. + fn increase_votes(&mut self, n: i32) { + let current_votes = self.get_votes(); + if n < 0 { + self.set_votes(current_votes.saturating_sub(n.abs() as u32)); + } else { + self.set_votes(current_votes + n as u32); + } + } } /// A trait for objects that have seats. @@ -16,9 +26,13 @@ pub trait WithSeats { fn set_seats(&mut self, seats: u16); /// Increases the number of seats by a given amount. - fn increase_seats(&mut self, n: u16) { - let actual_seats = self.get_seats(); - self.set_seats(actual_seats + n); + fn increase_seats(&mut self, n: i16) { + let current_seats = self.get_seats(); + if n < 0 { + self.set_seats(current_seats.saturating_sub(n.abs() as u16)); + } else { + self.set_seats(current_seats + n as u16); + } } } @@ -54,6 +68,7 @@ mod tests { struct Candidate { votes: u32, + seats: u16, } impl WithVotes for Candidate { @@ -66,13 +81,66 @@ mod tests { } } + impl WithSeats for Candidate { + fn get_seats(&self) -> u16 { + self.seats + } + + fn set_seats(&mut self, seats: u16) { + self.seats = seats; + } + } + #[test] fn test_with_votes() { - let mut candidate = Candidate { votes: 1000 }; + let mut candidate = Candidate { + votes: 1000, + seats: 0, + }; + + assert_eq!(candidate.get_votes(), 1000); + candidate.set_votes(2000); + assert_eq!(candidate.get_votes(), 2000); + + candidate.increase_votes(100); + assert_eq!(candidate.get_votes(), 2100); + + candidate.increase_votes(-200); + assert_eq!(candidate.get_votes(), 1900); + } + + #[test] + fn test_with_seats() { + let mut candidate = Candidate { + votes: 1000, + seats: 50, + }; + + assert_eq!(candidate.get_seats(), 50); + candidate.set_seats(100); + assert_eq!(candidate.get_seats(), 100); + + candidate.increase_seats(10); + assert_eq!(candidate.get_seats(), 110); + + candidate.increase_seats(-20); + assert_eq!(candidate.get_seats(), 90); + } + + #[test] + fn test_with_box() { + let mut candidate = Candidate { + votes: 1000, + seats: 50, + }; + let mut boxed_candidate = Box::new(&mut candidate); assert_eq!(boxed_candidate.get_votes(), 1000); boxed_candidate.set_votes(2000); - assert_eq!(candidate.get_votes(), 2000); + assert_eq!(boxed_candidate.get_votes(), 2000); + + boxed_candidate.set_seats(100); + assert_eq!(boxed_candidate.get_seats(), 100); } }