11// 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.
2+ // defined the `Fireworks` struct and a couple of functions that work with it.
3+ // Turn these free-standing functions into methods and associated functions
4+ // to express that relationship more clearly in the code.
5+
6+ #![ deny( clippy:: use_self) ] // practice using the `Self` type
37
48#[ derive( Debug ) ]
5- struct Package {
6- sender_country : String ,
7- recipient_country : String ,
8- weight_in_grams : u32 ,
9+ struct Fireworks {
10+ rockets : usize ,
911}
1012
11- impl 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- }
13+ // TODO: Turn this function into an associated function on `Fireworks`.
14+ fn new_fireworks ( ) -> Fireworks {
15+ Fireworks { rockets : 0 }
16+ }
2517
26- // TODO: Add the correct return type to the function signature.
27- fn is_international ( & self ) {
28- // TODO: Read the tests that use this method to find out when a package
29- // is considered international.
30- }
18+ // TODO: Turn this function into a method on `Fireworks`.
19+ fn add_rockets ( fireworks : & mut Fireworks , rockets : usize ) {
20+ fireworks. rockets += rockets
21+ }
3122
32- // TODO: Add the correct return type to the function signature.
33- fn get_fees ( & self , cents_per_gram : u32 ) {
34- // TODO: Calculate the package's fees.
23+ // TODO: Turn this function into a method on `Fireworks`.
24+ fn start ( fireworks : Fireworks ) -> String {
25+ if fireworks. rockets < 5 {
26+ String :: from ( "small" )
27+ } else if fireworks. rockets < 20 {
28+ String :: from ( "medium" )
29+ } else {
30+ String :: from ( "big" )
3531 }
3632}
3733
@@ -44,44 +40,19 @@ mod tests {
4440 use super :: * ;
4541
4642 #[ test]
47- #[ should_panic]
48- fn fail_creating_weightless_package ( ) {
49- let sender_country = String :: from ( "Spain" ) ;
50- let recipient_country = String :: from ( "Austria" ) ;
51-
52- Package :: new ( sender_country, recipient_country, 5 ) ;
53- }
54-
55- #[ test]
56- fn create_international_package ( ) {
57- let sender_country = String :: from ( "Spain" ) ;
58- let recipient_country = String :: from ( "Russia" ) ;
59-
60- let package = Package :: new ( sender_country, recipient_country, 1200 ) ;
61-
62- assert ! ( package. is_international( ) ) ;
63- }
64-
65- #[ test]
66- fn create_local_package ( ) {
67- let sender_country = String :: from ( "Canada" ) ;
68- let recipient_country = sender_country. clone ( ) ;
69-
70- let package = Package :: new ( sender_country, recipient_country, 1200 ) ;
71-
72- assert ! ( !package. is_international( ) ) ;
73- }
74-
75- #[ test]
76- fn calculate_transport_fees ( ) {
77- let sender_country = String :: from ( "Spain" ) ;
78- let recipient_country = String :: from ( "Spain" ) ;
79-
80- let cents_per_gram = 3 ;
81-
82- let package = Package :: new ( sender_country, recipient_country, 1500 ) ;
83-
84- assert_eq ! ( package. get_fees( cents_per_gram) , 4500 ) ;
85- assert_eq ! ( package. get_fees( cents_per_gram * 2 ) , 9000 ) ;
43+ fn start_some_fireworks ( ) {
44+ let mut f = Fireworks :: new ( ) ;
45+ f. add_rockets ( 3 ) ;
46+ assert_eq ! ( f. start( ) , "small" ) ;
47+
48+ let mut f = Fireworks :: new ( ) ;
49+ f. add_rockets ( 15 ) ;
50+ assert_eq ! ( f. start( ) , "medium" ) ;
51+
52+ let mut f = Fireworks :: new ( ) ;
53+ f. add_rockets ( 100 ) ;
54+ assert_eq ! ( Fireworks :: start( f) , "big" ) ;
55+ // We don't use method syntax in the last test to ensure the `start`
56+ // function takes ownership of the fireworks.
8657 }
8758}
0 commit comments