X-Git-Url: https://piware.de/gitweb/?p=learn-rust.git;a=blobdiff_plain;f=concepts%2Fsrc%2Fmain.rs;h=4b6df6447be9930e5773202f24601cd817722eb8;hp=06d122b9c4c727f399d8273312ffcfb2a95088fd;hb=HEAD;hpb=b653e9fe9d8492f2d4b5419721f7e00b392055f9 diff --git a/concepts/src/main.rs b/concepts/src/main.rs index 06d122b..be26bdb 100644 --- a/concepts/src/main.rs +++ b/concepts/src/main.rs @@ -1,9 +1,10 @@ -mod word_utils; mod lib; +mod word_utils; use std::collections::HashMap; -use std::io::{prelude::*, ErrorKind}; use std::fs::{self, File}; +use std::io::{prelude::*, ErrorKind}; +use std::{sync, thread, time}; use lib::*; use word_utils::{first_word, second_word}; @@ -14,7 +15,10 @@ fn test_strings() { println!("second word: '{}'", second_word(&s).unwrap()); let s2 = "hello dude blah"; - println!("second word of single: '{}'", second_word(s2).unwrap_or("(none)")); + println!( + "second word of single: '{}'", + second_word(s2).unwrap_or("(none)") + ); match second_word(s2) { Some(w) => println!("match: second word of '{}' exists: {}", s2, w), @@ -65,18 +69,25 @@ fn test_hashmaps() { println!("scores after doubling: {:?}", scores); // double scores of immutable hashmap (rebuild it) - let collect_scores: HashMap<_, _> = collect_scores.into_iter() + let collect_scores: HashMap<_, _> = collect_scores + .into_iter() .map(|(k, v)| (k, 2 * v)) .collect(); - println!("collect_scores after rebuilding with doubling: {:?}", collect_scores); + println!( + "collect_scores after rebuilding with doubling: {:?}", + collect_scores + ); } fn test_files() { if let Ok(mut f) = File::open("Cargo.toml") { let mut contents = String::new(); match f.read_to_string(&mut contents) { - Ok(len) => println!("successfully opened Cargo.toml: {:?}, contents {} bytes:\n{}\n----------", f, len, contents), - Err(e) => panic!("could not read file: {:?}", e) + Ok(len) => println!( + "successfully opened Cargo.toml: {:?}, contents {} bytes:\n{}\n----------", + f, len, contents + ), + Err(e) => panic!("could not read file: {:?}", e), } } else { println!("could not open Cargo.toml"); @@ -101,13 +112,13 @@ fn test_files() { // using the '?' operator match read_file("Cargo.toml") { Ok(s) => println!("Cargo.toml contents:\n{}\n-------------", s), - Err(e) => println!("Could not open Cargo.toml: {:?}", e) + Err(e) => println!("Could not open Cargo.toml: {:?}", e), } // using std API match fs::read_to_string("Cargo.toml") { Ok(s) => println!("Cargo.toml contents:\n{}\n-------------", s), - Err(e) => println!("Could not open Cargo.toml: {:?}", e) + Err(e) => println!("Could not open Cargo.toml: {:?}", e), } } @@ -124,7 +135,10 @@ fn test_generics() { println!("str_list: {:?}", str_list); let string_list = vec!["aaaa".to_string(), "xxxxx".to_string(), "ffff".to_string()]; - println!("largest string (with cloning): {}", largest_clone(&string_list)); + println!( + "largest string (with cloning): {}", + largest_clone(&string_list) + ); println!("largest string (with ref): {}", largest_ref(&string_list)); println!("string_list: {:?}", string_list); @@ -143,18 +157,36 @@ fn test_closures() { 2 * x }); - println!("1st int call for value 1: {}", expensive_int_result.value(1)); - println!("2nd int call for value 1: {}", expensive_int_result.value(1)); - println!("1st int call for value 2: {}", expensive_int_result.value(2)); + println!( + "1st int call for value 1: {}", + expensive_int_result.value(1) + ); + println!( + "2nd int call for value 1: {}", + expensive_int_result.value(1) + ); + println!( + "1st int call for value 2: {}", + expensive_int_result.value(2) + ); let mut expensive_str_result = Cacher::new(|x: &str| { println!("calculating expensive str result for {}", x); x.len() }); - println!("1st int call for value abc: {}", expensive_str_result.value("abc")); - println!("2nd int call for value abc: {}", expensive_str_result.value("abc")); - println!("1st int call for value defg: {}", expensive_str_result.value("defg")); + println!( + "1st int call for value abc: {}", + expensive_str_result.value("abc") + ); + println!( + "2nd int call for value abc: {}", + expensive_str_result.value("abc") + ); + println!( + "1st int call for value defg: {}", + expensive_str_result.value("defg") + ); } fn test_iterators() { @@ -189,6 +221,99 @@ fn test_iterators() { } } +fn test_threads() { + let t1 = thread::spawn(|| { + for i in 0..10 { + println!("hello #{} from thread", i); + thread::sleep(time::Duration::from_millis(1)); + } + }); + + for i in 1..5 { + println!("hello #{} from main", i); + thread::sleep(time::Duration::from_millis(1)); + } + + t1.join().unwrap(); + + // message passing + let (tx1, rx) = sync::mpsc::channel(); + let tx2 = tx1.clone(); + + let sender1 = thread::spawn(move || { + for s in ["hey", "from", "sender", "one"] { + tx1.send(s).expect("failed to send"); + thread::sleep(time::Duration::from_millis(100)); + } + }); + + let sender2 = thread::spawn(move || { + for s in ["Servus", "von", "Produzent", "zwei"] { + tx2.send(s).expect("failed to send"); + thread::sleep(time::Duration::from_millis(100)); + } + }); + + for received in rx { + println!("received {} from mpsc", received); + } + + sender1.join().unwrap(); + sender2.join().unwrap(); + + // shared state + let counter = sync::Arc::new(sync::Mutex::new(0)); + let mut threads = vec![]; + for _ in 0..10 { + let tc = sync::Arc::clone(&counter); + threads.push(thread::spawn(move || { + *tc.lock().unwrap() += 1; + })); + } + + for t in threads { + t.join().unwrap(); + } + + println!("counter: {}", *counter.lock().unwrap()); +} + +fn test_dyn_traits() { + let text = "I ate a salad for lunch today"; + let mut post = Post::new(); + post.add_text(text); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.reject(); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); // first + assert_eq!("", post.content()); + + post.approve(); // second + assert_eq!(text, post.content()); + + post.reject(); // no-op + assert_eq!(text, post.content()); +} + +fn test_state_types() { + let mut post = TPost::new(); + post.add_text("I ate a salad for lunch"); + let post = post.request_review(); + let mut post = post.reject(); + post.add_text(" today"); + let post = post.request_review(); + let post = post.approve(); + assert_eq!(post.content(), "I ate a salad for lunch today"); +} + fn main() { test_strings(); test_vectors(); @@ -197,4 +322,7 @@ fn main() { test_generics(); test_closures(); test_iterators(); + test_threads(); + test_dyn_traits(); + test_state_types(); }