完成rustlings

This commit is contained in:
chping 2024-02-19 13:57:24 +08:00
parent 5aa0a05c76
commit ed0b581e04
41 changed files with 301 additions and 110 deletions

View File

@ -6,9 +6,8 @@
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn main() {
let mut shopping_list: Vec<?> = Vec::new();
let mut shopping_list: Vec<&str> = Vec::new();
shopping_list.push("milk");
}

View File

@ -6,14 +6,13 @@
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
struct Wrapper {
value: u32,
struct Wrapper<T> {
value: T,
}
impl Wrapper {
pub fn new(value: u32) -> Self {
impl<T> Wrapper<T> {
pub fn new(value: T) -> Self {
Wrapper { value }
}
}

View File

@ -7,7 +7,7 @@
// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
trait AppendBar {
fn append_bar(self) -> Self;
@ -15,6 +15,9 @@ trait AppendBar {
impl AppendBar for String {
// TODO: Implement `AppendBar` for type `String`.
fn append_bar(self)->Self{
format!("{}Bar",self)
}
}
fn main() {

View File

@ -8,11 +8,16 @@
//
// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
trait AppendBar {
fn append_bar(self) -> Self;
}
impl AppendBar for Vec<String> {
fn append_bar(mut self)->Self{
self.push("Bar".to_string());
self
}
}
// TODO: Implement trait `AppendBar` for a vector of strings.

View File

@ -8,10 +8,11 @@
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
pub trait Licensed {
fn licensing_info(&self) -> String;
fn licensing_info(&self) -> String{
"Some information".to_string()
}
}
struct SomeSoftware {

View File

@ -7,7 +7,7 @@
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
pub trait Licensed {
fn licensing_info(&self) -> String {
@ -23,7 +23,7 @@ impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {}
// YOU MAY ONLY CHANGE THE NEXT LINE
fn compare_license_types(software: ??, software_two: ??) -> bool {
fn compare_license_types(software: impl Licensed, software_two:impl Licensed) -> bool {
software.licensing_info() == software_two.licensing_info()
}

View File

@ -7,7 +7,6 @@
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
pub trait SomeTrait {
fn some_function(&self) -> bool {
@ -30,7 +29,7 @@ impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {}
// YOU MAY ONLY CHANGE THE NEXT LINE
fn some_func(item: ??) -> bool {
fn some_func(item: impl SomeTrait + OtherTrait) -> bool {
item.some_function() && item.other_function()
}

View File

@ -8,9 +8,9 @@
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn longest(x: &str, y: &str) -> &str {
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {

View File

@ -6,7 +6,6 @@
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
@ -22,6 +21,8 @@ fn main() {
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
//移动打印行
println!("The longest string is '{}'", result);
}
println!("The longest string is '{}'", result);
}

View File

@ -5,11 +5,11 @@
// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
struct Book {
author: &str,
title: &str,
struct Book<'a> {
author: &'a str,
title: &'a str,
}
fn main() {

View File

@ -10,12 +10,13 @@
// Execute `rustlings hint tests1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[cfg(test)]
mod tests {
#[test]
fn you_can_assert() {
assert!();
// assert!(false);
assert!(true);
}
}

View File

@ -6,12 +6,14 @@
// Execute `rustlings hint tests2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[cfg(test)]
mod tests {
#[test]
fn you_can_assert_eq() {
assert_eq!();
// assert_eq!(true,false);
assert_eq!(true,true);
assert_eq!("a","a");
}
}

View File

@ -7,7 +7,7 @@
// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
pub fn is_even(num: i32) -> bool {
num % 2 == 0
@ -19,11 +19,11 @@ mod tests {
#[test]
fn is_true_when_even() {
assert!();
assert!(is_even(10));
}
#[test]
fn is_false_when_odd() {
assert!();
assert!(!is_even(11));
}
}

View File

@ -5,7 +5,7 @@
// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
struct Rectangle {
width: i32,
@ -30,17 +30,20 @@ mod tests {
fn correct_width_and_height() {
// This test should check if the rectangle is the size that we pass into its constructor
let rect = Rectangle::new(10, 20);
assert_eq!(???, 10); // check width
assert_eq!(???, 20); // check height
assert_eq!(rect.width, 10); // check width
assert_eq!(rect.height, 20); // check height
}
#[test]
#[should_panic]
fn negative_width() {
// This test should check if program panics when we try to create rectangle with negative width
let _rect = Rectangle::new(-10, 10);
}
#[test]
#[should_panic]
fn negative_height() {
// This test should check if program panics when we try to create rectangle with negative height
let _rect = Rectangle::new(10, -10);

View File

@ -9,18 +9,17 @@
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[test]
fn main() {
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
let mut my_iterable_fav_fruits = my_fav_fruits.iter(); // TODO: Step 1
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
assert_eq!(my_iterable_fav_fruits.next(), Some(&"custard apple")); // TODO: Step 2
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
assert_eq!(my_iterable_fav_fruits.next(), Some(&"peach")); // TODO: Step 3
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4
assert_eq!(my_iterable_fav_fruits.next(), None); // TODO: Step 4
}

View File

@ -6,7 +6,7 @@
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
// Step 1.
// Complete the `capitalize_first` function.
@ -15,7 +15,7 @@ pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars();
match c.next() {
None => String::new(),
Some(first) => ???,
Some(first) => first.to_uppercase().collect::<String>()+c.as_str(),
}
}
@ -24,7 +24,8 @@ pub fn capitalize_first(input: &str) -> String {
// Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
vec![]
words.iter().map(|v|{capitalize_first(v)}).collect::<Vec<String>>()
}
// Step 3.
@ -32,7 +33,11 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
String::new()
words.iter()
.map(|&word| capitalize_first(word))
.collect::<Vec<String>>()
.join("")
}
#[cfg(test)]

View File

@ -9,7 +9,6 @@
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[derive(Debug, PartialEq, Eq)]
pub enum DivisionError {
@ -26,23 +25,37 @@ pub struct NotDivisibleError {
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error.
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
todo!();
// todo!()
if b ==0 {
return Err(DivisionError::DivideByZero)
}
if a%b == 0{
return Ok(a/b)
}else{
return Err(DivisionError::NotDivisible(NotDivisibleError{ dividend: a,divisor: b}))
}
}
// Complete the function and return a value of the correct type so the test
// passes.
// Desired output: Ok([1, 11, 1426, 3])
fn result_with_list() -> () {
fn result_with_list() -> Result<Vec<i32>, DivisionError>{
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
let division_results: Result<Vec<i32>, DivisionError> = numbers.into_iter()
.map(|n| divide(n, 27))
.collect();
division_results
}
// Complete the function and return a value of the correct type so the test
// passes.
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
fn list_of_results() -> () {
fn list_of_results() -> Vec<Result<i32, DivisionError>> {
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
let division_results: Vec<Result<i32, DivisionError>> = numbers.into_iter()
.map(|n| divide(n, 27))
.collect();
division_results
}
#[cfg(test)]

View File

@ -3,9 +3,11 @@
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
pub fn factorial(num: u64) -> u64 {
// (1..=num).fold(1,|acc,x|acc*x)
(1..=num).product()
// Complete this function to return the factorial of num
// Do not use:
// - return

View File

@ -11,7 +11,6 @@
// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::collections::HashMap;
@ -35,7 +34,7 @@ fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
// map is a hashmap with String keys and Progress values.
// map = { "variables1": Complete, "from_str": None, ... }
todo!();
map.values().filter(|&val|val == & value).count()
}
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
@ -54,7 +53,10 @@ fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Pr
// collection is a slice of hashmaps.
// collection = [{ "variables1": Complete, "from_str": None, ... },
// { "variables2": Complete, ... }, ... ]
todo!();
collection.iter().map(|map|{
map.values().filter(|&val|val == & value).count()
}).sum()
}
#[cfg(test)]

View File

@ -21,7 +21,7 @@
//
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#![forbid(unused_imports)] // Do not change this, (or the next) line.
use std::sync::Arc;
@ -29,11 +29,11 @@ use std::thread;
fn main() {
let numbers: Vec<_> = (0..100u32).collect();
let shared_numbers = // TODO
let shared_numbers = Arc::new(numbers); // TODO
let mut joinhandles = Vec::new();
for offset in 0..8 {
let child_numbers = // TODO
let child_numbers =Arc::clone(&shared_numbers); // TODO
joinhandles.push(thread::spawn(move || {
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
println!("Sum of offset {} is {}", offset, sum);

View File

@ -18,11 +18,10 @@
//
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, List),
Cons(i32, Box<List>),
Nil,
}
@ -35,11 +34,13 @@ fn main() {
}
pub fn create_empty_list() -> List {
todo!()
List::Nil
}
//创建不为空的
pub fn create_non_empty_list() -> List {
todo!()
List::Cons(0,Box::new(List::Nil))
}
#[cfg(test)]

View File

@ -12,7 +12,7 @@
//
// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::borrow::Cow;
@ -49,6 +49,8 @@ mod tests {
let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) {
// TODO
Cow::Borrowed(_)=>{Ok(())}
_ => Err("Expected Borrowed value"),
}
}
@ -61,6 +63,8 @@ mod tests {
let mut input = Cow::from(slice);
match abs_all(&mut input) {
// TODO
Cow::Owned(_) => Ok(()),
_ => Err("Expected owned value"),
}
}
@ -73,6 +77,8 @@ mod tests {
let mut input = Cow::from(slice);
match abs_all(&mut input) {
// TODO
Cow::Owned(_) => Ok(()),
_ => Err("Expected owned value"),
}
}
}

View File

@ -10,7 +10,6 @@
//
// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::rc::Rc;
@ -61,17 +60,17 @@ fn main() {
jupiter.details();
// TODO
let saturn = Planet::Saturn(Rc::new(Sun {}));
let saturn = Planet::Saturn(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details();
// TODO
let uranus = Planet::Uranus(Rc::new(Sun {}));
let uranus = Planet::Uranus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
// TODO
let neptune = Planet::Neptune(Rc::new(Sun {}));
let neptune = Planet::Neptune(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
@ -91,13 +90,13 @@ fn main() {
drop(mars);
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
drop(earth);
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
drop(venus);
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
drop(mercury);
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference

View File

@ -8,7 +8,6 @@
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::thread;
use std::time::{Duration, Instant};
@ -27,6 +26,7 @@ fn main() {
let mut results: Vec<u128> = vec![];
for handle in handles {
// TODO: a struct is returned from thread::spawn, can you use it?
results.push(handle.join().unwrap())
}
if results.len() != 10 {

View File

@ -7,25 +7,26 @@
// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::sync::Mutex;
struct JobStatus {
jobs_completed: u32,
}
fn main() {
let status = Arc::new(JobStatus { jobs_completed: 0 });
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let mut handles = vec![];
for _ in 0..10 {
let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value
status_shared.jobs_completed += 1;
let mut status_shared_mut= status_shared.lock().unwrap();
status_shared_mut.jobs_completed += 1;
});
handles.push(handle);
}
@ -34,6 +35,7 @@ fn main() {
// TODO: Print the value of the JobStatus.jobs_completed. Did you notice
// anything interesting in the output? Do you have to 'join' on all the
// handles?
println!("jobs completed {}", ???);
let status = status.lock().unwrap();
println!("jobs completed {}", status.jobs_completed);
}
}

View File

@ -3,7 +3,7 @@
// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::sync::mpsc;
use std::sync::Arc;
@ -31,10 +31,12 @@ fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
let qc1 = Arc::clone(&qc);
let qc2 = Arc::clone(&qc);
//这里克隆一下,避免使用所有权转移
let tx_cloned = tx.clone();
thread::spawn(move || {
for val in &qc1.first_half {
println!("sending {:?}", val);
tx.send(*val).unwrap();
tx_cloned.send(*val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});

View File

@ -3,7 +3,6 @@
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
macro_rules! my_macro {
() => {
@ -12,5 +11,5 @@ macro_rules! my_macro {
}
fn main() {
my_macro();
my_macro!();
}

View File

@ -3,12 +3,14 @@
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn main() {
my_macro!();
}
#[macro_export]
macro_rules! my_macro {
() => {
println!("Check out my macro!");

View File

@ -5,9 +5,10 @@
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
mod macros {
#[macro_export] //导出定义的宏
macro_rules! my_macro {
() => {
println!("Check out my macro!");

View File

@ -3,13 +3,13 @@
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[rustfmt::skip]
macro_rules! my_macro {
() => {
println!("Check out my macro!");
}
};
($val:expr) => {
println!("Look at this other macro: {}", $val);
}

7
exercises/22_clippy/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "clippy3"
version = "0.0.1"

View File

@ -0,0 +1,7 @@
[package]
name = "clippy3"
version = "0.0.1"
edition = "2021"
[[bin]]
name = "clippy3"
path = "clippy3.rs"

View File

@ -9,12 +9,13 @@
// 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 = std::f32::consts::PI;
let radius = 5.00f32;
let area = pi * f32::powi(radius, 2);

View File

@ -3,12 +3,10 @@
// 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);

View File

@ -3,28 +3,31 @@
// Here's a couple more easy Clippy fixes, so you can see its utility.
// No hints.
// I AM NOT DONE
#[allow(unused_variables, unused_assignments)]
fn main() {
let my_option: Option<()> = None;
if my_option.is_none() {
my_option.unwrap();
}
// if my_option.is_none() {
// 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);
// let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
let mut my_empty_vec = vec![1, 2, 3, 4, 5];
my_empty_vec.clear();
println!("This Vec is empty, see? {:?}", my_empty_vec);
let mut value_a = 45;
let mut value_b = 66;
// Let's swap these two!
value_a = value_b;
value_b = value_a;
// value_a = value_b;
// value_b = value_a;
std::mem::swap(&mut value_a, &mut value_b);
println!("value a: {}; value b: {}", value_a, value_b);
}

View File

@ -7,25 +7,33 @@
// 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<T>(arg: T) -> usize {
fn byte_counter<T>(arg: T) -> usize
where T:AsRef<str>
{
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<T>(arg: T) -> usize {
fn char_counter<T>(arg: T) -> usize
where T:AsRef<str>
{
arg.as_ref().chars().count()
}
//TODO 这里后续看看怎么有其他的方式进行修改
// Squares a number using as_mut().
// TODO: Add the appropriate trait bound.
fn num_sq<T>(arg: &mut T) {
fn num_sq<T>(arg: &mut T)
where T:AsMut<u32>
{
// TODO: Implement the function body.
???
let slice = arg.as_mut();
*slice = *slice * *slice
}
#[cfg(test)]

View File

@ -40,10 +40,36 @@ 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 {
if s.len() == 0 {
return Person::default();
}
let s_vec = s.split(",").collect::<Vec<&str>>();
if s_vec.len() <2{
return Person::default();
}
let mut persion = Person::default();
let name = s_vec[0].to_string();
if name.len() == 0 {
return Person::default();
}
let age = s_vec[1];
if age.len() == 0 {
return Person::default();
}
let age = if let Ok(age) = age.parse::<usize>() {
age
} else {
return Person::default();
};
Person {
name: name,
age: age,
}
}
}

View File

@ -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
@ -49,12 +48,64 @@ enum ParsePersonError {
// you want to return a string error message, you can do so via just using
// return `Err("my error message".into())`.
//没有使用索引获取的
// impl FromStr for Person {
// type Err = ParsePersonError;
// fn from_str(s: &str) -> Result<Person, Self::Err> {
// if s.is_empty(){
// return Err(ParsePersonError::Empty);
// }
// let mut parts = s.split(",");
// if parts.clone().count() !=2{
// return Err(ParsePersonError::BadLen);
// }
// let name= parts.next().unwrap_or("").to_string();
// let age = parts.next().unwrap_or("").to_string();
// if name.is_empty() {
// return Err(ParsePersonError::NoName);
// }
// let age = match age.parse::<usize>(){
// Ok(age) =>age,
// Err(e) =>return Err(ParsePersonError::ParseInt(e))
// };
// Ok(Person{
// name,
// age
// })
// }
// }
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
if s.is_empty() {
return Err(ParsePersonError::Empty);
}
let parts: Vec<&str> = s.split(',').collect();
if parts.len() != 2 {
return Err(ParsePersonError::BadLen);
}
let name = parts[0].to_string();
if name.is_empty() {
return Err(ParsePersonError::NoName);
}
let age = match parts[1].parse::<usize>() {
Ok(age) => age,
Err(e) => return Err(ParsePersonError::ParseInt(e)),
};
Ok(Person { name, age })
}
}
fn main() {
let p = "Mark,20".parse::<Person>().unwrap();
println!("{:?}", p);

View File

@ -27,7 +27,7 @@ enum IntoColorError {
IntConversion,
}
// I AM NOT DONE
// 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
@ -40,7 +40,26 @@ enum IntoColorError {
// Tuple implementation
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error>
{
let (red,green,blue) = tuple;
if red <0 ||red>255{
return Err(IntoColorError::IntConversion)
}
if green <0 ||green>255{
return Err(IntoColorError::IntConversion)
}
if blue <0 ||blue>255{
return Err(IntoColorError::IntConversion)
}
Ok(Color{
red:red as u8,
green: green as u8,
blue:blue as u8,
})
}
}
@ -48,6 +67,19 @@ impl TryFrom<(i16, i16, i16)> for Color {
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
for &value in &arr {
if value < 0 || value > 255 {
return Err(IntoColorError::IntConversion);
}
}
let arr = arr.iter().map(|f|*f as u8).collect::<Vec<u8>>();
Ok(Color{
red:arr[0],
green:arr[1],
blue:arr[2],
})
}
}
@ -55,6 +87,20 @@ impl TryFrom<[i16; 3]> for Color {
impl TryFrom<&[i16]> for Color {
type Error = IntoColorError;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
if slice.len() ==3{
for &value in slice {
if value < 0 || value > 255 {
return Err(IntoColorError::IntConversion);
}
}
Ok(Color{
red:slice[0] as u8,
green:slice[1] as u8,
blue:slice[2] as u8,
})
}else{
return Err(IntoColorError::BadLen);
}
}
}

View File

@ -10,11 +10,10 @@
// 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::<f64>();
total / values.len()
total / values.len() as f64
}
fn main() {

View File

@ -16,15 +16,14 @@
//
// Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
pub struct ReportCard {
pub grade: f32,
pub struct ReportCard<T> {
pub grade: T,
pub student_name: String,
pub student_age: u8,
}
impl ReportCard {
impl<T:std::fmt::Display> ReportCard<T> {
pub fn print(&self) -> String {
format!("{} ({}) - achieved a grade of {}",
&self.student_name, &self.student_age, &self.grade)
@ -52,7 +51,7 @@ mod tests {
fn generate_alphabetic_report_card() {
// TODO: Make sure to change the grade here after you finish the exercise.
let report_card = ReportCard {
grade: 2.1,
grade:"A+",
student_name: "Gary Plotter".to_string(),
student_age: 11,
};