From 55cc8584bdec5023637e2f6985e4df129401ea8b Mon Sep 17 00:00:00 2001 From: Kacper Poneta Date: Thu, 11 Jul 2024 22:53:38 +0200 Subject: [PATCH 1/5] added exercise --- exercises/14_generics/generics3.rs | 35 +++++++++++++++++++++++++++ rustlings-macros/info.toml | 14 +++++++++++ solutions/14_generics/generics3.rs | 38 ++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 exercises/14_generics/generics3.rs create mode 100644 solutions/14_generics/generics3.rs diff --git a/exercises/14_generics/generics3.rs b/exercises/14_generics/generics3.rs new file mode 100644 index 00000000..e90b3250 --- /dev/null +++ b/exercises/14_generics/generics3.rs @@ -0,0 +1,35 @@ +// generics3.rs +// Execute `rustlings hint generics3` or use the `hint` watch subcommand for a hint. + +// TODO Use your knowledge of generics to enchance the `stringify` function by only changing the signature. +fn stringify(list: &[&str]) -> String { + let items_str = list + .iter() + .map(|e| e.to_string()) + .collect::>() + .join(", "); + format!("[{items_str}]") +} + +fn main() { + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn store_str_on_list() { + let names_list = vec!["maria", "jacob", "kacper"]; + let stringified = stringify(&names_list); + assert_eq!(stringified, "[maria, jacob, kacper]".to_string()); + } + + #[test] + fn store_numbers_on_list() { + let numbers_list = vec![1, 2, 3]; + let stringified = stringify(&numbers_list); + assert_eq!(stringified, "[1, 2, 3]".to_string()); + } +} \ No newline at end of file diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml index e69834ac..feced7c8 100644 --- a/rustlings-macros/info.toml +++ b/rustlings-macros/info.toml @@ -741,6 +741,20 @@ hint = """ Related section in The Book: https://doc.rust-lang.org/book/ch10-01-syntax.html#in-method-definitions""" +[[exercises]] +name = "generics3" +dir = "14_generics" +hint = """ +Vectors in Rust use generics to create dynamically-sized arrays of any type. +The stringify function takes a vector as an argument, but only accepts vectors that store the &str type. +To allow the function to accept vectors that store any type, you can leverage your knowledge about generics. +If you're unsure how to proceed, please refer to the Rust Book at: +https://doc.rust-lang.org/book/ch10-01-syntax.html#in-function-definitions. + +*Please note that in `stringify` we want to use `.to_string()` on vector elements +Refer to this: https://doc.rust-lang.org/book/ch10-02-traits.html +""" + # TRAITS [[exercises]] diff --git a/solutions/14_generics/generics3.rs b/solutions/14_generics/generics3.rs new file mode 100644 index 00000000..165fb6ad --- /dev/null +++ b/solutions/14_generics/generics3.rs @@ -0,0 +1,38 @@ +// generics3.rs +// Execute `rustlings hint generics3` or use the `hint` watch subcommand for a hint. + +// Here we add generic in function declaration so function can work with different types +fn stringify(list: &Vec) -> String +where + T: ToString // here we also specify that T needs to implement ToString trait so we can use .to_string() on the vetor elements +{ + let items_str = list + .iter() + .map(|e| e.to_string()) + .collect::>() + .join(", "); + format!("[{items_str}]") +} + +fn main() { + // You can optionally experiment here. +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn store_str_on_list() { + let names_list = vec!["maria", "jacob", "kacper"]; + let stringified = stringify(&names_list); + assert_eq!(stringified, "[maria, jacob, kacper]".to_string()); + } + + #[test] + fn store_numbers_on_list() { + let numbers_list = vec![1, 2, 3]; + let stringified = stringify(&numbers_list); + assert_eq!(stringified, "[1, 2, 3]".to_string()); + } +} \ No newline at end of file From 938b90e5f26b95aad4e11109015463bb03cd3e5f Mon Sep 17 00:00:00 2001 From: Kacper Poneta Date: Thu, 11 Jul 2024 22:55:48 +0200 Subject: [PATCH 2/5] very small solution update --- solutions/14_generics/generics3.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/14_generics/generics3.rs b/solutions/14_generics/generics3.rs index 165fb6ad..240e1e00 100644 --- a/solutions/14_generics/generics3.rs +++ b/solutions/14_generics/generics3.rs @@ -2,7 +2,7 @@ // Execute `rustlings hint generics3` or use the `hint` watch subcommand for a hint. // Here we add generic in function declaration so function can work with different types -fn stringify(list: &Vec) -> String +fn stringify(list: &[T]) -> String where T: ToString // here we also specify that T needs to implement ToString trait so we can use .to_string() on the vetor elements { From 52af0674c1e2e306b8af8e6abf06074eb028e9fc Mon Sep 17 00:00:00 2001 From: Kacper Poneta Date: Fri, 12 Jul 2024 18:14:40 +0200 Subject: [PATCH 3/5] changed the task to make it more appropriate --- exercises/14_generics/generics3.rs | 47 +++++++++++++++++++++--------- rustlings-macros/info.toml | 5 +--- solutions/14_generics/generics3.rs | 47 +++++++++++++++++++----------- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/exercises/14_generics/generics3.rs b/exercises/14_generics/generics3.rs index e90b3250..662d1b96 100644 --- a/exercises/14_generics/generics3.rs +++ b/exercises/14_generics/generics3.rs @@ -1,14 +1,13 @@ // generics3.rs // Execute `rustlings hint generics3` or use the `hint` watch subcommand for a hint. -// TODO Use your knowledge of generics to enchance the `stringify` function by only changing the signature. -fn stringify(list: &[&str]) -> String { - let items_str = list - .iter() - .map(|e| e.to_string()) - .collect::>() - .join(", "); - format!("[{items_str}]") +// This function should take an array of `Option` elements and returns array of not None elements +// TODO fix this function signature +fn into_dispose_nulls(list: Vec>) -> Vec<&str> { + list + .into_iter() + .flatten() + .collect() } fn main() { @@ -21,15 +20,35 @@ mod tests { #[test] fn store_str_on_list() { - let names_list = vec!["maria", "jacob", "kacper"]; - let stringified = stringify(&names_list); - assert_eq!(stringified, "[maria, jacob, kacper]".to_string()); + let names_list = vec![Some("maria"), Some("jacob"), None, Some("kacper"), None]; + let only_values = into_dispose_nulls(names_list); + assert_eq!(only_values.len(), 3); } #[test] fn store_numbers_on_list() { - let numbers_list = vec![1, 2, 3]; - let stringified = stringify(&numbers_list); - assert_eq!(stringified, "[1, 2, 3]".to_string()); + let numbers_list = vec![Some(1), Some(2), None, Some(3)]; + let only_values = into_dispose_nulls(numbers_list); + assert_eq!(only_values.len(), 3); } + + #[test] + fn store_custom_type_on_list() { + #[allow(dead_code)] + struct Rectangle { + width: i32, + height: i32 + } + impl Rectangle { + fn new(width: i32, height: i32) -> Self { + Self { width, height } + } + } + + let custom_list = vec![Some(Rectangle::new(1, 2)), None, None, Some(Rectangle::new(3, 4))]; + let only_values = into_dispose_nulls(custom_list); + assert_eq!(only_values.len(), 2); + } + + } \ No newline at end of file diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml index feced7c8..78fb3c93 100644 --- a/rustlings-macros/info.toml +++ b/rustlings-macros/info.toml @@ -746,13 +746,10 @@ name = "generics3" dir = "14_generics" hint = """ Vectors in Rust use generics to create dynamically-sized arrays of any type. -The stringify function takes a vector as an argument, but only accepts vectors that store the &str type. +The `into_dispose_nulls` function takes a vector as an argument, but only accepts vectors that store the &str type. To allow the function to accept vectors that store any type, you can leverage your knowledge about generics. If you're unsure how to proceed, please refer to the Rust Book at: https://doc.rust-lang.org/book/ch10-01-syntax.html#in-function-definitions. - -*Please note that in `stringify` we want to use `.to_string()` on vector elements -Refer to this: https://doc.rust-lang.org/book/ch10-02-traits.html """ # TRAITS diff --git a/solutions/14_generics/generics3.rs b/solutions/14_generics/generics3.rs index 240e1e00..73046993 100644 --- a/solutions/14_generics/generics3.rs +++ b/solutions/14_generics/generics3.rs @@ -1,17 +1,13 @@ // generics3.rs // Execute `rustlings hint generics3` or use the `hint` watch subcommand for a hint. -// Here we add generic in function declaration so function can work with different types -fn stringify(list: &[T]) -> String -where - T: ToString // here we also specify that T needs to implement ToString trait so we can use .to_string() on the vetor elements -{ - let items_str = list - .iter() - .map(|e| e.to_string()) - .collect::>() - .join(", "); - format!("[{items_str}]") +// Here we added generic type `T` to function signature +// Now this function can be used with vector of any +fn into_dispose_nulls(list: Vec>) -> Vec { + list + .into_iter() + .flatten() + .collect() } fn main() { @@ -24,15 +20,32 @@ mod tests { #[test] fn store_str_on_list() { - let names_list = vec!["maria", "jacob", "kacper"]; - let stringified = stringify(&names_list); - assert_eq!(stringified, "[maria, jacob, kacper]".to_string()); + let names_list = vec![Some("maria"), Some("jacob"), None, Some("kacper"), None]; + let only_values = into_dispose_nulls(names_list); + assert_eq!(only_values.len(), 3); } #[test] fn store_numbers_on_list() { - let numbers_list = vec![1, 2, 3]; - let stringified = stringify(&numbers_list); - assert_eq!(stringified, "[1, 2, 3]".to_string()); + let numbers_list = vec![Some(1), Some(2), None, Some(3)]; + let only_values = into_dispose_nulls(numbers_list); + assert_eq!(only_values.len(), 3); + } + + #[test] + fn store_custom_type_on_list() { + struct Rectangle { + width: i32, + height: i32 + } + impl Rectangle { + fn new(width: i32, height: i32) -> Self { + Self { width, height } + } + } + + let custom_list = vec![Some(Rectangle::new(1, 2)), None, None, Some(Rectangle::new(3, 4))]; + let only_values = into_dispose_nulls(custom_list); + assert_eq!(only_values.len(), 2); } } \ No newline at end of file From 4c8365fe88392b30695aad76d65e7f147728b74f Mon Sep 17 00:00:00 2001 From: mo8it Date: Fri, 12 Jul 2024 18:25:01 +0200 Subject: [PATCH 4/5] Update dev/Cargo.toml --- dev/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/Cargo.toml b/dev/Cargo.toml index 7f3acb51..9cb657da 100644 --- a/dev/Cargo.toml +++ b/dev/Cargo.toml @@ -116,6 +116,8 @@ bin = [ { name = "generics1_sol", path = "../solutions/14_generics/generics1.rs" }, { name = "generics2", path = "../exercises/14_generics/generics2.rs" }, { name = "generics2_sol", path = "../solutions/14_generics/generics2.rs" }, + { name = "generics3", path = "../exercises/14_generics/generics3.rs" }, + { name = "generics3_sol", path = "../solutions/14_generics/generics3.rs" }, { name = "traits1", path = "../exercises/15_traits/traits1.rs" }, { name = "traits1_sol", path = "../solutions/15_traits/traits1.rs" }, { name = "traits2", path = "../exercises/15_traits/traits2.rs" }, From 59e8f70e55fdcb5d8dcda651254f52cfdd76ce1f Mon Sep 17 00:00:00 2001 From: mo8it Date: Fri, 12 Jul 2024 18:31:23 +0200 Subject: [PATCH 5/5] Format code --- exercises/14_generics/generics3.rs | 18 +++++++++--------- solutions/14_generics/generics3.rs | 16 +++++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/exercises/14_generics/generics3.rs b/exercises/14_generics/generics3.rs index 662d1b96..a60b396a 100644 --- a/exercises/14_generics/generics3.rs +++ b/exercises/14_generics/generics3.rs @@ -4,10 +4,7 @@ // This function should take an array of `Option` elements and returns array of not None elements // TODO fix this function signature fn into_dispose_nulls(list: Vec>) -> Vec<&str> { - list - .into_iter() - .flatten() - .collect() + list.into_iter().flatten().collect() } fn main() { @@ -37,7 +34,7 @@ mod tests { #[allow(dead_code)] struct Rectangle { width: i32, - height: i32 + height: i32, } impl Rectangle { fn new(width: i32, height: i32) -> Self { @@ -45,10 +42,13 @@ mod tests { } } - let custom_list = vec![Some(Rectangle::new(1, 2)), None, None, Some(Rectangle::new(3, 4))]; + let custom_list = vec![ + Some(Rectangle::new(1, 2)), + None, + None, + Some(Rectangle::new(3, 4)), + ]; let only_values = into_dispose_nulls(custom_list); assert_eq!(only_values.len(), 2); } - - -} \ No newline at end of file +} diff --git a/solutions/14_generics/generics3.rs b/solutions/14_generics/generics3.rs index 73046993..8c137ec1 100644 --- a/solutions/14_generics/generics3.rs +++ b/solutions/14_generics/generics3.rs @@ -4,10 +4,7 @@ // Here we added generic type `T` to function signature // Now this function can be used with vector of any fn into_dispose_nulls(list: Vec>) -> Vec { - list - .into_iter() - .flatten() - .collect() + list.into_iter().flatten().collect() } fn main() { @@ -36,7 +33,7 @@ mod tests { fn store_custom_type_on_list() { struct Rectangle { width: i32, - height: i32 + height: i32, } impl Rectangle { fn new(width: i32, height: i32) -> Self { @@ -44,8 +41,13 @@ mod tests { } } - let custom_list = vec![Some(Rectangle::new(1, 2)), None, None, Some(Rectangle::new(3, 4))]; + let custom_list = vec![ + Some(Rectangle::new(1, 2)), + None, + None, + Some(Rectangle::new(3, 4)), + ]; let only_values = into_dispose_nulls(custom_list); assert_eq!(only_values.len(), 2); } -} \ No newline at end of file +}