//! Your task is to implement the three required methods for `Rocket` //! to make the tests pass. Consult the tests for guidance. //! //! Bonus bonus task: Add documentation comments to all Rocket's methods. use std::marker::PhantomData; const ESCAPE_VELOCITY: u32 = 11_186; /// A rocket sitting on the ground with at least one cat #[derive(Debug)] struct Grounded; /// A rocket flying in outer space with some velocity #[derive(Debug)] struct Launched; /// A rocket crashed due to undefined behavior with no cat videos left #[derive(Debug)] struct Crashed; #[derive(Debug)] struct Rocket { stage: PhantomData, velocity: u32, crew: u32, } impl Rocket { pub fn new() -> Self { Self { stage: PhantomData, velocity: 0, // Not moving crew: 1, // One captain } } pub fn add_crew(&mut self, more_cats: u32) { self.crew += more_cats; } pub fn launch(self) -> Rocket { assert_eq!(self.velocity, 0); // This is harder to make invariant using types Rocket:: { stage: PhantomData, velocity: ESCAPE_VELOCITY, crew: self.crew, } } } impl Rocket<___> { // TODO } #[cfg(test)] mod tests { use super::*; #[test] fn grounded_rocket() { let mut rocket = Rocket::new(); rocket.add_crew(5); assert!(matches!( rocket, Rocket:: { crew: 6, velocity: 0, .. } )) } /// Rocket should be able to change its velocity with `accelerate` #[test] fn launched_rocket() { let mut rocket = Rocket::new(); rocket.add_crew(5); let mut rocket = rocket.launch(); rocket.accelerate(100); assert!(matches!( rocket, Rocket:: { crew: 6, velocity: 11_286, .. } )) } /// Rocket should be able to `try_land`, which will be successful /// if its velocity is zero, otherwise it will crash with no cat videos left #[test] fn houston_we_have_had_a_problem() { let mut rocket = Rocket::new(); let rocket = rocket.launch(); let crashed: Result> = rocket.try_land(); assert_eq!(crashed.unwrap_err().crew, 0) } /// Rocket should be able to change its velocity with `decelerate` #[test] fn landing_successful() { let mut rocket = Rocket::new(); rocket.add_crew(5); let mut rocket = rocket.launch(); rocket.decelerate(11_186); let landed = rocket.try_land(); assert!(matches!( landed, Ok(Rocket:: { crew: 6, velocity: 0, .. }) )) } }