From e5225cb7c880283d9afb9f21b2b13ad2ba776e00 Mon Sep 17 00:00:00 2001 From: Esteban Escobar Date: Sat, 18 Feb 2023 08:37:13 -0500 Subject: [PATCH] almost done --- REVISITS.md | 7 ++++++- exercises/clippy/clippy1.rs | 4 +--- exercises/clippy/clippy2.rs | 4 +--- exercises/clippy/clippy3.rs | 13 ++++++------- exercises/conversions/from_into.rs | 21 +++++++++++++++++++-- exercises/conversions/using_as.rs | 4 +--- exercises/macros/macros1.rs | 5 ++--- exercises/macros/macros2.rs | 3 +-- exercises/macros/macros3.rs | 3 +-- exercises/macros/macros4.rs | 4 +--- exercises/threads/threads1.rs | 7 +++---- exercises/threads/threads2.rs | 10 +++++----- exercises/threads/threads3.rs | 19 ++++++++++++------- 13 files changed, 59 insertions(+), 45 deletions(-) diff --git a/REVISITS.md b/REVISITS.md index b79030fd..f29c4903 100644 --- a/REVISITS.md +++ b/REVISITS.md @@ -30,6 +30,11 @@ return results to new Vec vector 31) box.rs for smart pointer to allocate memory in recursive types 32) arc.rs for atomic reference counters, moving ownershup to thread::spawn. 33) rc.rs Rc::strong_count, Rc::new and Rc::clone, and drop(). Also note "In summary, if you need shared ownership in a single-threaded context, you can use Rc. If you need shared ownership across multiple threads, you should use Arc." Rc is faster and smaller than Arc +34) Cow +35) All threads exercises :(. handles and join methods for thread completion wait in the main thread. +36) threads2 exercises important for understanding synchorization primitize Mutex +37) threads3 - again - all threads exercises. +38) all macros exercises -clippy conversions macros threads +conversions diff --git a/exercises/clippy/clippy1.rs b/exercises/clippy/clippy1.rs index bad46891..7b411fab 100644 --- a/exercises/clippy/clippy1.rs +++ b/exercises/clippy/clippy1.rs @@ -6,12 +6,10 @@ // check clippy's suggestions from the output to solve the exercise. // 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 dac40dbe..48d82440 100644 --- a/exercises/clippy/clippy2.rs +++ b/exercises/clippy/clippy2.rs @@ -1,12 +1,10 @@ // clippy2.rs // 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 { + if let Some(x) = option { res += x; } println!("{}", res); diff --git a/exercises/clippy/clippy3.rs b/exercises/clippy/clippy3.rs index b0159ebe..a2043c5a 100644 --- a/exercises/clippy/clippy3.rs +++ b/exercises/clippy/clippy3.rs @@ -1,28 +1,27 @@ // clippy3.rs // Here's a couple more easy Clippy fixes, so you can see its utility. -// I AM NOT DONE - #[allow(unused_variables, unused_assignments)] fn main() { let my_option: Option<()> = None; - if my_option.is_none() { + if let Some(x) = my_option { 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].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; + std::mem::swap(&mut value_a, &mut value_b); + // value_a = value_b; + // value_b = value_a; println!("value a: {}; value b: {}", value_a, value_b); } diff --git a/exercises/conversions/from_into.rs b/exercises/conversions/from_into.rs index 6c272c3b..269e048e 100644 --- a/exercises/conversions/from_into.rs +++ b/exercises/conversions/from_into.rs @@ -35,10 +35,27 @@ 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.to_string().len() == 0 { + Person::default() + } else { + let person_attr: Vec<&str> = s.split(",").collect(); + match person_attr.len() { + 2 => match person_attr[0] { + "" => Person::default(), + _ => match person_attr[1] { + "" => Person::default(), + _ => match person_attr[1].parse::() { + Ok(person_age) => Person{name: person_attr[0].to_string(), age: person_age}, + Err(_) => Person::default() + } + } + }, + _ => Person::default() + } + + } } } diff --git a/exercises/conversions/using_as.rs b/exercises/conversions/using_as.rs index 8c9b7113..0d961ca0 100644 --- a/exercises/conversions/using_as.rs +++ b/exercises/conversions/using_as.rs @@ -6,11 +6,9 @@ // and returns the proper type. // 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/macros/macros1.rs b/exercises/macros/macros1.rs index 634d0a70..5fde0806 100644 --- a/exercises/macros/macros1.rs +++ b/exercises/macros/macros1.rs @@ -1,8 +1,7 @@ // macros1.rs // Execute `rustlings hint macros1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - +#[macro_export] macro_rules! my_macro { () => { println!("Check out my macro!"); @@ -10,5 +9,5 @@ macro_rules! my_macro { } fn main() { - my_macro(); + my_macro!(); } diff --git a/exercises/macros/macros2.rs b/exercises/macros/macros2.rs index f6092cab..e2a9d915 100644 --- a/exercises/macros/macros2.rs +++ b/exercises/macros/macros2.rs @@ -1,12 +1,11 @@ // macros2.rs // 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!"); diff --git a/exercises/macros/macros3.rs b/exercises/macros/macros3.rs index 106f1c6d..302da074 100644 --- a/exercises/macros/macros3.rs +++ b/exercises/macros/macros3.rs @@ -2,8 +2,7 @@ // Make me compile, without taking the macro out of the module! // Execute `rustlings hint macros3` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - +#[macro_use] mod macros { macro_rules! my_macro { () => { diff --git a/exercises/macros/macros4.rs b/exercises/macros/macros4.rs index c1fc5e8b..9e7a225c 100644 --- a/exercises/macros/macros4.rs +++ b/exercises/macros/macros4.rs @@ -1,12 +1,10 @@ // macros4.rs // Execute `rustlings hint macros4` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - macro_rules! my_macro { () => { println!("Check out my macro!"); - } + }; ($val:expr) => { println!("Look at this other macro: {}", $val); } diff --git a/exercises/threads/threads1.rs b/exercises/threads/threads1.rs index e59f4ce4..b31c63a5 100644 --- a/exercises/threads/threads1.rs +++ b/exercises/threads/threads1.rs @@ -2,8 +2,6 @@ // Execute `rustlings hint threads1` or use the `hint` watch subcommand for a hint. // This program should wait until all the spawned threads have finished before exiting. -// I AM NOT DONE - use std::thread; use std::time::Duration; @@ -12,15 +10,16 @@ fn main() { let mut handles = vec![]; for i in 0..10 { - thread::spawn(move || { + handles.push(thread::spawn(move || { thread::sleep(Duration::from_millis(250)); println!("thread {} is complete", i); - }); + })); } let mut completed_threads = 0; for handle in handles { // TODO: a struct is returned from thread::spawn, can you use it? + handle.join().unwrap(); completed_threads += 1; } diff --git a/exercises/threads/threads2.rs b/exercises/threads/threads2.rs index ada3d14a..8c7371d3 100644 --- a/exercises/threads/threads2.rs +++ b/exercises/threads/threads2.rs @@ -3,25 +3,25 @@ // Building on the last exercise, we want all of the threads to complete their work but this time // the spawned threads need to be in charge of updating a shared value: JobStatus.jobs_completed -// 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 = (*status_shared).lock().unwrap(); //do a deref so you can do lock on Mutex sync primitive + status.jobs_completed += 1; }); handles.push(handle); } @@ -29,6 +29,6 @@ fn main() { handle.join().unwrap(); // 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 {}", ???); + println!("jobs completed {}", status.lock().unwrap().jobs_completed); } } diff --git a/exercises/threads/threads3.rs b/exercises/threads/threads3.rs index 9e9f285a..37b94000 100644 --- a/exercises/threads/threads3.rs +++ b/exercises/threads/threads3.rs @@ -1,10 +1,8 @@ // threads3.rs // 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; +use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; @@ -24,23 +22,29 @@ impl Queue { } } -fn send_tx(q: Queue, tx: mpsc::Sender) -> () { +fn send_tx(q: Queue, mytx: Arc>>) -> () { let qc = Arc::new(q); let qc1 = Arc::clone(&qc); let qc2 = Arc::clone(&qc); + let tx1 = Arc::clone(&mytx); + thread::spawn(move || { for val in &qc1.first_half { println!("sending {:?}", val); - tx.send(*val).unwrap(); + let mytx = tx1.lock().unwrap(); + mytx.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); + let tx2 = Arc::clone(&mytx); + thread::spawn(move || { for val in &qc2.second_half { println!("sending {:?}", val); - tx.send(*val).unwrap(); + let mytx = tx2.lock().unwrap(); + mytx.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); @@ -51,7 +55,8 @@ fn main() { let queue = Queue::new(); let queue_length = queue.length; - send_tx(queue, tx); + let newtx = Arc::new(Mutex::new(tx)); + send_tx(queue, newtx); let mut total_received: u32 = 0; for received in rx {