1// Structs contain data, but can also have logic. In this exercise, we have
2// defined the `Package` struct, and we want to test some logic attached to it.
3
4#[derive(Debug)]
5struct Package {
6 sender_country: String,
7 recipient_country: String,
8 weight_in_grams: u32,
9}
10
11impl Package {
12 fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Self {
13 if weight_in_grams < 10 {
14 // This isn't how you should handle errors in Rust, but we will
15 // learn about error handling later.
16 panic!("Can't ship a package with weight below 10 grams");
17 }
18
19 Self {
20 sender_country,
21 recipient_country,
22 weight_in_grams,
23 }
24 }
25
26 // TODO: Add the correct return type to the function signature.
27 fn is_international(&self) -> bool {
28 // TODO: Read the tests that use this method to find out when a package
29 // is considered international.
30 self.sender_country != self.recipient_country
31 }
32
33 // TODO: Add the correct return type to the function signature.
34 fn get_fees(&self, cents_per_gram: u32) -> u32 {
35 // TODO: Calculate the package's fees.
36 self.weight_in_grams * cents_per_gram
37 }
38}
39
40fn main() {
41 // You can optionally experiment here.
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 #[should_panic]
50 fn fail_creating_weightless_package() {
51 let sender_country = String::from("Spain");
52 let recipient_country = String::from("Austria");
53
54 Package::new(sender_country, recipient_country, 5);
55 }
56
57 #[test]
58 fn create_international_package() {
59 let sender_country = String::from("Spain");
60 let recipient_country = String::from("Russia");
61
62 let package = Package::new(sender_country, recipient_country, 1200);
63
64 assert!(package.is_international());
65 }
66
67 #[test]
68 fn create_local_package() {
69 let sender_country = String::from("Canada");
70 let recipient_country = sender_country.clone();
71
72 let package = Package::new(sender_country, recipient_country, 1200);
73
74 assert!(!package.is_international());
75 }
76
77 #[test]
78 fn calculate_transport_fees() {
79 let sender_country = String::from("Spain");
80 let recipient_country = String::from("Spain");
81
82 let cents_per_gram = 3;
83
84 let package = Package::new(sender_country, recipient_country, 1500);
85
86 assert_eq!(package.get_fees(cents_per_gram), 4500);
87 assert_eq!(package.get_fees(cents_per_gram * 2), 9000);
88 }
89}