diff --git a/exercises/clippy/clippy1.rs b/exercises/clippy/clippy1.rs index 95c0141f4..6b6664825 100644 --- a/exercises/clippy/clippy1.rs +++ b/exercises/clippy/clippy1.rs @@ -9,12 +9,11 @@ // Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE use std::f32; fn main() { - let pi = 3.14f32; + let pi = f32::consts::PI; let radius = 5.00f32; let area = pi * f32::powi(radius, 2); diff --git a/exercises/clippy/clippy2.rs b/exercises/clippy/clippy2.rs index 9b87a0b70..605070bf4 100644 --- a/exercises/clippy/clippy2.rs +++ b/exercises/clippy/clippy2.rs @@ -3,12 +3,11 @@ // Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE fn main() { let mut res = 42; let option = Some(12); - for x in option { + while let Some(x) = option { res += x; } println!("{}", res); diff --git a/exercises/clippy/clippy3.rs b/exercises/clippy/clippy3.rs index 35021f841..3128483c7 100644 --- a/exercises/clippy/clippy3.rs +++ b/exercises/clippy/clippy3.rs @@ -4,28 +4,28 @@ // // Execute `rustlings hint clippy3` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE + +use std::mem::swap; #[allow(unused_variables, unused_assignments)] fn main() { let my_option: Option<()> = None; if my_option.is_none() { - my_option.unwrap(); + // my_option.unwrap(); } let my_arr = &[ - -1, -2, -3 + -1, -2, -3, -4, -5, -6 ]; println!("My array! Here it is: {:?}", my_arr); - let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5); - println!("This Vec is empty, see? {:?}", my_empty_vec); + // let my_empty_vec = + println!("This Vec is empty, see? {:?}", vec![1, 2, 3, 4, 5].resize(0, 5)); let mut value_a = 45; let mut value_b = 66; // Let's swap these two! - value_a = value_b; - value_b = value_a; + swap(&mut value_a, &mut value_b); println!("value a: {}; value b: {}", value_a, value_b); } diff --git a/exercises/conversions/as_ref_mut.rs b/exercises/conversions/as_ref_mut.rs index 626a36c45..c2915df75 100644 --- a/exercises/conversions/as_ref_mut.rs +++ b/exercises/conversions/as_ref_mut.rs @@ -7,25 +7,28 @@ // Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE // Obtain the number of bytes (not characters) in the given argument. // TODO: Add the AsRef trait appropriately as a trait bound. -fn byte_counter(arg: T) -> usize { + +use std::ops::Mul; + +fn byte_counter>(arg: T) -> usize { arg.as_ref().as_bytes().len() } // Obtain the number of characters (not bytes) in the given argument. // TODO: Add the AsRef trait appropriately as a trait bound. -fn char_counter(arg: T) -> usize { +fn char_counter>(arg: T) -> usize { arg.as_ref().chars().count() } // Squares a number using as_mut(). // TODO: Add the appropriate trait bound. -fn num_sq(arg: &mut T) { +fn num_sq>(arg: &mut T) { // TODO: Implement the function body. - ??? + let value = arg.as_mut(); + *value *= *value; } #[cfg(test)] diff --git a/exercises/conversions/from_into.rs b/exercises/conversions/from_into.rs index aba471d92..8f61cd4fa 100644 --- a/exercises/conversions/from_into.rs +++ b/exercises/conversions/from_into.rs @@ -40,10 +40,38 @@ impl Default for Person { // If while parsing the age, something goes wrong, then return the default of // Person Otherwise, then return an instantiated Person object with the results -// I AM NOT DONE impl From<&str> for Person { fn from(s: &str) -> Person { + // 如果字符串为空,返回默认的 Person + if s.is_empty() { + return Person::default(); + } + + // 使用 split_once 分割字符串 + let (name, age_str) = s.split_once(',').unwrap_or(("", "")); + + // 如果名字为空,返回默认的 Person + if name.trim().is_empty() { + return Person::default(); + } + + // 尝试解析年龄,如果失败则返回默认的 Person + let age = match age_str.trim().parse::() { + Ok(x) if x < 150 && x > 0 => x, + _ => return Person::default() + }; + + // 检查年龄是否在合理范围内 + if age > 150 { + return Person::default(); + } + + // 返回解析后的 Person 对象 + Person { + name: name.trim().to_string(), + age, + } } } diff --git a/exercises/conversions/from_str.rs b/exercises/conversions/from_str.rs index 34472c32c..e77972f86 100644 --- a/exercises/conversions/from_str.rs +++ b/exercises/conversions/from_str.rs @@ -31,7 +31,6 @@ enum ParsePersonError { ParseInt(ParseIntError), } -// I AM NOT DONE // Steps: // 1. If the length of the provided string is 0, an error should be returned @@ -52,6 +51,38 @@ enum ParsePersonError { impl FromStr for Person { type Err = ParsePersonError; fn from_str(s: &str) -> Result { + if s.is_empty() { + return Err(ParsePersonError::Empty); + } + + let elems: Vec<_> = s.split(',').collect(); + + if elems.len() > 2 || elems.len() <= 1 { + return Err(ParsePersonError::BadLen); + } + + let name = elems[0]; + let age_str = elems[1]; + + // 如果名字为空,返回默认的 Person + if name.trim().is_empty() { + return Err(ParsePersonError::NoName); + } + + // 尝试解析年龄,如果失败则返回默认的 Person + let age = age_str.trim().parse::() + .map_err(ParsePersonError::ParseInt)?; + + // 检查年龄是否在合理范围内 + if age > 150 || age<=0 { + return Err(ParsePersonError::BadLen); + } + + // 返回解析后的 Person 对象 + Ok(Person { + name: name.trim().to_string(), + age, + }) } } diff --git a/exercises/conversions/try_from_into.rs b/exercises/conversions/try_from_into.rs index 32d6ef39e..83347a611 100644 --- a/exercises/conversions/try_from_into.rs +++ b/exercises/conversions/try_from_into.rs @@ -9,7 +9,9 @@ // Execute `rustlings hint try_from_into` or use the `hint` watch subcommand for // a hint. +use std::array::TryFromSliceError; use std::convert::{TryFrom, TryInto}; +use std::num::TryFromIntError; #[derive(Debug, PartialEq)] struct Color { @@ -27,7 +29,13 @@ enum IntoColorError { IntConversion, } -// I AM NOT DONE +impl From for IntoColorError { + fn from(err: TryFromIntError) -> Self { + IntoColorError::IntConversion + } +} + + // Your task is to complete this implementation and return an Ok result of inner // type Color. You need to create an implementation for a tuple of three @@ -41,6 +49,16 @@ enum IntoColorError { impl TryFrom<(i16, i16, i16)> for Color { type Error = IntoColorError; fn try_from(tuple: (i16, i16, i16)) -> Result { + // let (a,b,c) = tuple; + // let red:Result = a.try_into(); + // let green:Result = b.try_into(); + // let blue:Result = c.try_into(); + + Ok(Color{ + red: u8::try_from(tuple.0)?, + green: u8::try_from(tuple.1)?, + blue: u8::try_from(tuple.2)?, + }) } } @@ -48,6 +66,11 @@ impl TryFrom<(i16, i16, i16)> for Color { impl TryFrom<[i16; 3]> for Color { type Error = IntoColorError; fn try_from(arr: [i16; 3]) -> Result { + Ok(Color{ + red: u8::try_from(arr[0])?, + green: u8::try_from(arr[1])?, + blue: u8::try_from(arr[2])?, + }) } } @@ -55,6 +78,14 @@ impl TryFrom<[i16; 3]> for Color { impl TryFrom<&[i16]> for Color { type Error = IntoColorError; fn try_from(slice: &[i16]) -> Result { + if slice.len() != 3 { + return Err(IntoColorError::BadLen); + } + Ok(Color{ + red: u8::try_from(slice[0])?, + green: u8::try_from(slice[1])?, + blue: u8::try_from(slice[2])?, + }) } } diff --git a/exercises/conversions/using_as.rs b/exercises/conversions/using_as.rs index 414cef3a0..a9f1e4496 100644 --- a/exercises/conversions/using_as.rs +++ b/exercises/conversions/using_as.rs @@ -10,11 +10,9 @@ // Execute `rustlings hint using_as` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn average(values: &[f64]) -> f64 { let total = values.iter().sum::(); - total / values.len() + total / values.len() as f64 } fn main() { diff --git a/exercises/tests/Cargo.lock b/exercises/tests/Cargo.lock new file mode 100644 index 000000000..d3a8d8c09 --- /dev/null +++ b/exercises/tests/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "tests8" +version = "0.0.1" diff --git a/exercises/tests/Cargo.toml b/exercises/tests/Cargo.toml new file mode 100644 index 000000000..646d1f04e --- /dev/null +++ b/exercises/tests/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tests8" +version = "0.0.1" +edition = "2021" +[[bin]] +name = "tests8" +path = "tests8.rs" \ No newline at end of file diff --git a/exercises/tests/build.rs b/exercises/tests/build.rs index aa518cef2..ec128cc75 100644 --- a/exercises/tests/build.rs +++ b/exercises/tests/build.rs @@ -10,15 +10,26 @@ fn main() { .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); // What's the use of this timestamp here? - let your_command = format!( - "Your command here with {}, please checkout exercises/tests/build.rs", - timestamp - ); - println!("cargo:{}", your_command); + // let your_command = format!( + // "Your command here with {}, please checkout exercises/tests/build.rs", + // timestamp + // ); + // println!("cargo:{}", your_command); + + let command = format!("rustc-env=TEST_FOO={}", timestamp); + println!("cargo:{}", command); + + // let command2 = ""; + // println!("cargo:rustc-cfg=feature=\"pass\""); + // println!("cargo:rustc-cfg=feature=\"pass\""); + // println!("cargo:rustc-cfg=pass"); + + // In tests8, we should enable "pass" feature to make the // testcase return early. Fill in the command to tell // Cargo about that. - let your_command = "Your command here, please checkout exercises/tests/build.rs"; - println!("cargo:{}", your_command); + println!("cargo:rustc-cfg=feature=\"pass\""); + // let your_command = "Your command here, please checkout exercises/tests/build.rs"; + // println!("cargo:{}", your_command); } diff --git a/exercises/tests/tests5.rs b/exercises/tests/tests5.rs index 0cd5cb256..7f3af2a6e 100644 --- a/exercises/tests/tests5.rs +++ b/exercises/tests/tests5.rs @@ -22,7 +22,6 @@ // Execute `rustlings hint tests5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE /// # Safety /// @@ -31,8 +30,9 @@ unsafe fn modify_by_address(address: usize) { // TODO: Fill your safety notice of the code block below to match your // code's behavior and the contract of this function. You may use the // comment of the test below as your format reference. - unsafe { - todo!("Your code goes here") + let ptr = address as *mut u32; + if !ptr.is_null() { + *ptr = 0xAABBCCDD; // Modify the u32 value to 0xAABBCCDD } } @@ -45,7 +45,7 @@ mod tests { let mut t: u32 = 0x12345678; // SAFETY: The address is guaranteed to be valid and contains // a unique reference to a `u32` local variable. - unsafe { modify_by_address(&mut t as *mut u32 as usize) }; + unsafe {modify_by_address(&mut t as *mut u32 as usize);} assert!(t == 0xAABBCCDD); } } diff --git a/exercises/tests/tests6.rs b/exercises/tests/tests6.rs index 4c913779d..bbe0971cd 100644 --- a/exercises/tests/tests6.rs +++ b/exercises/tests/tests6.rs @@ -7,7 +7,6 @@ // Execute `rustlings hint tests6` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE struct Foo { a: u128, @@ -20,8 +19,9 @@ struct Foo { unsafe fn raw_pointer_to_box(ptr: *mut Foo) -> Box { // SAFETY: The `ptr` contains an owned box of `Foo` by contract. We // simply reconstruct the box from that pointer. - let mut ret: Box = unsafe { ??? }; - todo!("The rest of the code goes here") + let mut ret: Box = unsafe { Box::from_raw(ptr) }; + ret.b = Some("hello".to_owned()); + ret } #[cfg(test)] diff --git a/exercises/tests/tests7.rs b/exercises/tests/tests7.rs index 66b37b72d..b7345898d 100644 --- a/exercises/tests/tests7.rs +++ b/exercises/tests/tests7.rs @@ -34,9 +34,18 @@ // Execute `rustlings hint tests7` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE -fn main() {} +use core::time; + +fn main() { + // let timestamp = std::time::SystemTime::now() + // .duration_since(std::time::UNIX_EPOCH) + // .unwrap() + // .as_secs(); + + // let command = format!("rustc-env=TEST_FOO={}", timestamp); + // println!("cargo:{}", command); +} #[cfg(test)] mod tests { @@ -48,6 +57,7 @@ mod tests { .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); + let s = std::env::var("TEST_FOO").unwrap(); let e: u64 = s.parse().unwrap(); assert!(timestamp >= e && timestamp < e + 10); diff --git a/exercises/tests/tests8.rs b/exercises/tests/tests8.rs index ce7e35d8d..b9eb0fb10 100644 --- a/exercises/tests/tests8.rs +++ b/exercises/tests/tests8.rs @@ -7,7 +7,6 @@ // Execute `rustlings hint tests8` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE fn main() {} diff --git a/exercises/tests/tests9.rs b/exercises/tests/tests9.rs index ea2a8ec02..8e54a5c8e 100644 --- a/exercises/tests/tests9.rs +++ b/exercises/tests/tests9.rs @@ -27,15 +27,16 @@ // // You should NOT modify any existing code except for adding two lines of attributes. -// I AM NOT DONE extern "Rust" { fn my_demo_function(a: u32) -> u32; + #[link_name = "my_demo_function"] fn my_demo_function_alias(a: u32) -> u32; } mod Foo { // No `extern` equals `extern "Rust"`. + #[no_mangle] fn my_demo_function(a: u32) -> u32 { a }