diff options
| author | Hunter Kvalevog <hunter@kvog.sh> | 2026-09-27 15:47:45 -0500 |
|---|---|---|
| committer | Hunter Kvalevog <hunter@kvog.sh> | 2026-09-27 15:47:45 -0500 |
| commit | e7c14ea67e4a39789e7c1dd3a264c61a9c14050e (patch) | |
| tree | 1e823328e2b1975a53c0ce45b3e3bcc0e89bad67 /rustlings | |
| parent | c7eff9175d93ada8b6d50b511d7027a91b1a184b (diff) | |
rustlings: complete 15
Diffstat (limited to 'rustlings')
| -rw-r--r-- | rustlings/.rustlings-state.txt | 10 | ||||
| -rw-r--r-- | rustlings/exercises/15_traits/traits1.rs | 3 | ||||
| -rw-r--r-- | rustlings/exercises/15_traits/traits2.rs | 8 | ||||
| -rw-r--r-- | rustlings/exercises/15_traits/traits3.rs | 4 | ||||
| -rw-r--r-- | rustlings/exercises/15_traits/traits4.rs | 2 | ||||
| -rw-r--r-- | rustlings/exercises/15_traits/traits5.rs | 2 | ||||
| -rw-r--r-- | rustlings/exercises/quizzes/quiz3.rs | 6 | ||||
| -rw-r--r-- | rustlings/solutions/15_traits/traits1.rs | 32 | ||||
| -rw-r--r-- | rustlings/solutions/15_traits/traits2.rs | 27 | ||||
| -rw-r--r-- | rustlings/solutions/15_traits/traits3.rs | 36 | ||||
| -rw-r--r-- | rustlings/solutions/15_traits/traits4.rs | 35 | ||||
| -rw-r--r-- | rustlings/solutions/15_traits/traits5.rs | 39 | ||||
| -rw-r--r-- | rustlings/solutions/quizzes/quiz3.rs | 65 |
13 files changed, 249 insertions, 20 deletions
diff --git a/rustlings/.rustlings-state.txt b/rustlings/.rustlings-state.txt index 163f806..888d577 100644 --- a/rustlings/.rustlings-state.txt +++ b/rustlings/.rustlings-state.txt @@ -1,6 +1,6 @@ DON'T EDIT THIS FILE! -traits1 +lifetimes1 intro1 intro2 @@ -59,4 +59,10 @@ errors4 errors5 errors6 generics1 -generics2
\ No newline at end of file +generics2 +traits1 +traits2 +traits3 +traits4 +traits5 +quiz3
\ No newline at end of file diff --git a/rustlings/exercises/15_traits/traits1.rs b/rustlings/exercises/15_traits/traits1.rs index 85be17e..fad6a50 100644 --- a/rustlings/exercises/15_traits/traits1.rs +++ b/rustlings/exercises/15_traits/traits1.rs @@ -6,6 +6,9 @@ trait AppendBar { impl AppendBar for String { // TODO: Implement `AppendBar` for the type `String`. + fn append_bar(self) -> Self { + self + "Bar" + } } fn main() { diff --git a/rustlings/exercises/15_traits/traits2.rs b/rustlings/exercises/15_traits/traits2.rs index d724dc2..5dfc36d 100644 --- a/rustlings/exercises/15_traits/traits2.rs +++ b/rustlings/exercises/15_traits/traits2.rs @@ -5,6 +5,14 @@ trait AppendBar { // TODO: Implement the trait `AppendBar` for a vector of strings. // `append_bar` should push the string "Bar" into the vector. +impl AppendBar for Vec<String> { + fn append_bar(self) -> Self { + let mut s = self.clone(); + s.push(String::from("Bar")); + s + } +} + fn main() { // You can optionally experiment here. } diff --git a/rustlings/exercises/15_traits/traits3.rs b/rustlings/exercises/15_traits/traits3.rs index c244650..144ac0a 100644 --- a/rustlings/exercises/15_traits/traits3.rs +++ b/rustlings/exercises/15_traits/traits3.rs @@ -3,7 +3,9 @@ trait Licensed { // implementors like the two structs below can share that default behavior // without repeating the function. // The default license information should be the string "Default license". - fn licensing_info(&self) -> String; + fn licensing_info(&self) -> String { + String::from("Default license") + } } struct SomeSoftware { diff --git a/rustlings/exercises/15_traits/traits4.rs b/rustlings/exercises/15_traits/traits4.rs index 80092a6..b23dcdd 100644 --- a/rustlings/exercises/15_traits/traits4.rs +++ b/rustlings/exercises/15_traits/traits4.rs @@ -11,7 +11,7 @@ impl Licensed for SomeSoftware {} impl Licensed for OtherSoftware {} // TODO: Fix the compiler error by only changing the signature of this function. -fn compare_license_types(software1: ???, software2: ???) -> bool { +fn compare_license_types(software1: impl Licensed, software2: impl Licensed) -> bool { software1.licensing_info() == software2.licensing_info() } diff --git a/rustlings/exercises/15_traits/traits5.rs b/rustlings/exercises/15_traits/traits5.rs index 5b356ac..6548014 100644 --- a/rustlings/exercises/15_traits/traits5.rs +++ b/rustlings/exercises/15_traits/traits5.rs @@ -19,7 +19,7 @@ impl SomeTrait for OtherStruct {} impl OtherTrait for OtherStruct {} // TODO: Fix the compiler error by only changing the signature of this function. -fn some_func(item: ???) -> bool { +fn some_func<T : SomeTrait + OtherTrait>(item: T) -> bool { item.some_function() && item.other_function() } diff --git a/rustlings/exercises/quizzes/quiz3.rs b/rustlings/exercises/quizzes/quiz3.rs index c877c5f..5bb859f 100644 --- a/rustlings/exercises/quizzes/quiz3.rs +++ b/rustlings/exercises/quizzes/quiz3.rs @@ -12,14 +12,14 @@ // block to support alphabetical report cards in addition to numerical ones. // TODO: Adjust the struct as described above. -struct ReportCard { - grade: f32, +struct ReportCard<T> { + grade: T, student_name: String, student_age: u8, } // TODO: Adjust the impl block as described above. -impl ReportCard { +impl<T: std::fmt::Display> ReportCard<T> { fn print(&self) -> String { format!( "{} ({}) - achieved a grade of {}", diff --git a/rustlings/solutions/15_traits/traits1.rs b/rustlings/solutions/15_traits/traits1.rs index dcf2377..790873f 100644 --- a/rustlings/solutions/15_traits/traits1.rs +++ b/rustlings/solutions/15_traits/traits1.rs @@ -1,4 +1,32 @@ +// The trait `AppendBar` has only one function which appends "Bar" to any object +// implementing this trait. +trait AppendBar { + fn append_bar(self) -> Self; +} + +impl AppendBar for String { + fn append_bar(self) -> Self { + self + "Bar" + } +} + fn main() { - // DON'T EDIT THIS SOLUTION FILE! - // It will be automatically filled after you finish the exercise. + let s = String::from("Foo"); + let s = s.append_bar(); + println!("s: {s}"); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_foo_bar() { + assert_eq!(String::from("Foo").append_bar(), "FooBar"); + } + + #[test] + fn is_bar_bar() { + assert_eq!(String::from("").append_bar().append_bar(), "BarBar"); + } } diff --git a/rustlings/solutions/15_traits/traits2.rs b/rustlings/solutions/15_traits/traits2.rs index dcf2377..0db93e0 100644 --- a/rustlings/solutions/15_traits/traits2.rs +++ b/rustlings/solutions/15_traits/traits2.rs @@ -1,4 +1,27 @@ +trait AppendBar { + fn append_bar(self) -> Self; +} + +impl AppendBar for Vec<String> { + fn append_bar(mut self) -> Self { + // ^^^ this is important + self.push(String::from("Bar")); + self + } +} + fn main() { - // DON'T EDIT THIS SOLUTION FILE! - // It will be automatically filled after you finish the exercise. + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_vec_pop_eq_bar() { + let mut foo = vec![String::from("Foo")].append_bar(); + assert_eq!(foo.pop().unwrap(), "Bar"); + assert_eq!(foo.pop().unwrap(), "Foo"); + } } diff --git a/rustlings/solutions/15_traits/traits3.rs b/rustlings/solutions/15_traits/traits3.rs index dcf2377..3d8ec85 100644 --- a/rustlings/solutions/15_traits/traits3.rs +++ b/rustlings/solutions/15_traits/traits3.rs @@ -1,4 +1,36 @@ +trait Licensed { + fn licensing_info(&self) -> String { + "Default license".to_string() + } +} + +struct SomeSoftware { + version_number: i32, +} + +struct OtherSoftware { + version_number: String, +} + +impl Licensed for SomeSoftware {} +impl Licensed for OtherSoftware {} + fn main() { - // DON'T EDIT THIS SOLUTION FILE! - // It will be automatically filled after you finish the exercise. + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_licensing_info_the_same() { + let licensing_info = "Default license"; + let some_software = SomeSoftware { version_number: 1 }; + let other_software = OtherSoftware { + version_number: "v2.0.0".to_string(), + }; + assert_eq!(some_software.licensing_info(), licensing_info); + assert_eq!(other_software.licensing_info(), licensing_info); + } } diff --git a/rustlings/solutions/15_traits/traits4.rs b/rustlings/solutions/15_traits/traits4.rs index dcf2377..3675b8d 100644 --- a/rustlings/solutions/15_traits/traits4.rs +++ b/rustlings/solutions/15_traits/traits4.rs @@ -1,4 +1,35 @@ +trait Licensed { + fn licensing_info(&self) -> String { + "Default license".to_string() + } +} + +struct SomeSoftware; +struct OtherSoftware; + +impl Licensed for SomeSoftware {} +impl Licensed for OtherSoftware {} + +fn compare_license_types(software1: impl Licensed, software2: impl Licensed) -> bool { + // ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ + software1.licensing_info() == software2.licensing_info() +} + fn main() { - // DON'T EDIT THIS SOLUTION FILE! - // It will be automatically filled after you finish the exercise. + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn compare_license_information() { + assert!(compare_license_types(SomeSoftware, OtherSoftware)); + } + + #[test] + fn compare_license_information_backwards() { + assert!(compare_license_types(OtherSoftware, SomeSoftware)); + } } diff --git a/rustlings/solutions/15_traits/traits5.rs b/rustlings/solutions/15_traits/traits5.rs index dcf2377..1fb426a 100644 --- a/rustlings/solutions/15_traits/traits5.rs +++ b/rustlings/solutions/15_traits/traits5.rs @@ -1,4 +1,39 @@ +trait SomeTrait { + fn some_function(&self) -> bool { + true + } +} + +trait OtherTrait { + fn other_function(&self) -> bool { + true + } +} + +struct SomeStruct; +impl SomeTrait for SomeStruct {} +impl OtherTrait for SomeStruct {} + +struct OtherStruct; +impl SomeTrait for OtherStruct {} +impl OtherTrait for OtherStruct {} + +fn some_func(item: impl SomeTrait + OtherTrait) -> bool { + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + item.some_function() && item.other_function() +} + fn main() { - // DON'T EDIT THIS SOLUTION FILE! - // It will be automatically filled after you finish the exercise. + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_some_func() { + assert!(some_func(SomeStruct)); + assert!(some_func(OtherStruct)); + } } diff --git a/rustlings/solutions/quizzes/quiz3.rs b/rustlings/solutions/quizzes/quiz3.rs index dcf2377..7b91278 100644 --- a/rustlings/solutions/quizzes/quiz3.rs +++ b/rustlings/solutions/quizzes/quiz3.rs @@ -1,4 +1,65 @@ +// An imaginary magical school has a new report card generation system written +// in Rust! Currently, the system only supports creating report cards where the +// student's grade is represented numerically (e.g. 1.0 -> 5.5). However, the +// school also issues alphabetical grades (A+ -> F-) and needs to be able to +// print both types of report card! +// +// Make the necessary code changes in the struct `ReportCard` and the impl +// block to support alphabetical report cards in addition to numerical ones. + +use std::fmt::Display; + +// Make the struct generic over `T`. +struct ReportCard<T> { + // ^^^ + grade: T, + // ^ + student_name: String, + student_age: u8, +} + +// To be able to print the grade, it has to implement the `Display` trait. +impl<T: Display> ReportCard<T> { + // ^^^^^^^ require that `T` implements `Display`. + fn print(&self) -> String { + format!( + "{} ({}) - achieved a grade of {}", + &self.student_name, &self.student_age, &self.grade, + ) + } +} + fn main() { - // DON'T EDIT THIS SOLUTION FILE! - // It will be automatically filled after you finish the exercise. + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn generate_numeric_report_card() { + let report_card = ReportCard { + grade: 2.1, + student_name: "Tom Wriggle".to_string(), + student_age: 12, + }; + assert_eq!( + report_card.print(), + "Tom Wriggle (12) - achieved a grade of 2.1", + ); + } + + #[test] + fn generate_alphabetic_report_card() { + let report_card = ReportCard { + grade: "A+", + student_name: "Gary Plotter".to_string(), + student_age: 11, + }; + assert_eq!( + report_card.print(), + "Gary Plotter (11) - achieved a grade of A+", + ); + } } |