diff --git a/exercises/07_structs/structs3.rs b/exercises/07_structs/structs3.rs index 10adb487..18a6cc98 100644 --- a/exercises/07_structs/structs3.rs +++ b/exercises/07_structs/structs3.rs @@ -1,6 +1,5 @@ // Structs contain data, but can also have logic. In this exercise we have -// defined the Package struct and we want to test some logic attached to it. -// Make the code compile and the tests pass! +// defined the `Package` struct and we want to test some logic attached to it. #[derive(Debug)] struct Package { @@ -10,26 +9,28 @@ struct Package { } impl Package { - fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Package { + fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Self { if weight_in_grams < 10 { - // This is not how you should handle errors in Rust, - // but we will learn about error handling later. - panic!("Can not ship a package with weight below 10 grams.") - } else { - Package { - sender_country, - recipient_country, - weight_in_grams, - } + // This isn't how you should handle errors in Rust, but we will + // learn about error handling later. + panic!("Can't ship a package with weight below 10 grams"); + } + + Self { + sender_country, + recipient_country, + weight_in_grams, } } - fn is_international(&self) -> ??? { - // Something goes here... + // TODO: Add the correct return type to the function signature. + fn is_international(&self) { + // TODO: Read the tests that use this method to find out when a package is concidered international. } - fn get_fees(&self, cents_per_gram: u32) -> ??? { - // Something goes here... + // TODO: Add the correct return type to the function signature. + fn get_fees(&self, cents_per_gram: u32) { + // TODO: Calculate the package's fees. } } diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml index 08bbd74d..7535b682 100644 --- a/rustlings-macros/info.toml +++ b/rustlings-macros/info.toml @@ -434,7 +434,7 @@ the places it goes through right? For `get_fees`: This method takes an additional argument, is there a field in the `Package` struct that this relates to? -Have a look in The Book, to find out more about method implementations: +Have a look in The Book to find out more about method implementations: https://doc.rust-lang.org/book/ch05-03-method-syntax.html""" # ENUMS diff --git a/solutions/07_structs/structs3.rs b/solutions/07_structs/structs3.rs index 4e181989..3f878cc8 100644 --- a/solutions/07_structs/structs3.rs +++ b/solutions/07_structs/structs3.rs @@ -1 +1,83 @@ -// Solutions will be available before the stable release. Thank you for testing the beta version 🥰 +#[derive(Debug)] +struct Package { + sender_country: String, + recipient_country: String, + weight_in_grams: u32, +} + +impl Package { + fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Self { + if weight_in_grams < 10 { + // This isn't how you should handle errors in Rust, but we will + // learn about error handling later. + panic!("Can't ship a package with weight below 10 grams"); + } + + Self { + sender_country, + recipient_country, + weight_in_grams, + } + } + + fn is_international(&self) -> bool { + // ^^^^^^^ added + self.sender_country != self.recipient_country + } + + fn get_fees(&self, cents_per_gram: u32) -> u32 { + // ^^^^^^ added + self.weight_in_grams * cents_per_gram + } +} + +fn main() { + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn fail_creating_weightless_package() { + let sender_country = String::from("Spain"); + let recipient_country = String::from("Austria"); + + Package::new(sender_country, recipient_country, 5); + } + + #[test] + fn create_international_package() { + let sender_country = String::from("Spain"); + let recipient_country = String::from("Russia"); + + let package = Package::new(sender_country, recipient_country, 1200); + + assert!(package.is_international()); + } + + #[test] + fn create_local_package() { + let sender_country = String::from("Canada"); + let recipient_country = sender_country.clone(); + + let package = Package::new(sender_country, recipient_country, 1200); + + assert!(!package.is_international()); + } + + #[test] + fn calculate_transport_fees() { + let sender_country = String::from("Spain"); + let recipient_country = String::from("Spain"); + + let cents_per_gram = 3; + + let package = Package::new(sender_country, recipient_country, 1500); + + assert_eq!(package.get_fees(cents_per_gram), 4500); + assert_eq!(package.get_fees(cents_per_gram * 2), 9000); + } +}