diff --git a/chapter9/Cargo.lock b/chapter9/Cargo.lock new file mode 100644 index 0000000..b697b15 --- /dev/null +++ b/chapter9/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter9" +version = "0.1.0" diff --git a/chapter9/Cargo.toml b/chapter9/Cargo.toml new file mode 100644 index 0000000..370a967 --- /dev/null +++ b/chapter9/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "chapter9" +version = "0.1.0" +authors = ["peshwar9"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "message-passing" +path = "src/message-passing.rs" + +[[bin]] +name = "shared-state" +path = "src/shared-state.rs" + +[dependencies] diff --git a/chapter9/dirnames.txt b/chapter9/dirnames.txt new file mode 100644 index 0000000..42305e8 --- /dev/null +++ b/chapter9/dirnames.txt @@ -0,0 +1,6 @@ +/Users//rust/project1 +/Users//rust/project2 +/Users//rust/project3 +/Users//rust/project4 +/Users//rust/project5 + diff --git a/chapter9/src/message-passing.rs b/chapter9/src/message-passing.rs new file mode 100644 index 0000000..aa2b241 --- /dev/null +++ b/chapter9/src/message-passing.rs @@ -0,0 +1,27 @@ +use std::sync::mpsc; +use std::thread; + +fn main() { + let (transmitter1, receiver) = mpsc::channel(); + + let transmitter2 = mpsc::Sender::clone(&transmitter1); + + thread::spawn(move || { + let num_vec: Vec = vec!["One".into(), "two".into(), "three".into(), "four".into()]; + for num in num_vec { + transmitter1.send(num).unwrap(); + } + }); + + thread::spawn(move || { + let num_vec: Vec = + vec!["Five".into(), "Six".into(), "Seven".into(), "eight".into()]; + for num in num_vec { + transmitter2.send(num).unwrap(); + } + }); + + for received_val in receiver { + println!("Received from thread: {}", received_val); + } +} diff --git a/chapter9/src/shared-state.rs b/chapter9/src/shared-state.rs new file mode 100644 index 0000000..e6de068 --- /dev/null +++ b/chapter9/src/shared-state.rs @@ -0,0 +1,76 @@ +use std::ffi::OsStr; +use std::fs; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; +use std::thread; + +#[derive(Debug)] +pub struct SrcStats { + pub number_of_files: u32, + pub loc: u32, + pub comments: u32, + pub blanks: u32, +} + +fn main() { + let src_stats = SrcStats { + number_of_files: 0, + loc: 0, + comments: 0, + blanks: 0, + }; + let stats_counter = Arc::new(Mutex::new(src_stats)); + + let mut dir_list = File::open("./dirnames.txt").unwrap(); + let reader = BufReader::new(&mut dir_list); + let dir_lines: Vec<_> = reader.lines().collect(); + + let mut child_handles = vec![]; + for dir in dir_lines { + let dir = dir.unwrap(); + let src_stats = Arc::clone(&stats_counter); + + let handle = thread::spawn(move || { + let mut dir_entries = vec![PathBuf::from(dir)]; + let mut file_entries = vec![]; + while let Some(entry) = dir_entries.pop() { + for inner_entry in fs::read_dir(&entry).unwrap() { + if let Ok(entry) = inner_entry { + if entry.path().is_dir() { + dir_entries.push(entry.path()); + } else { + if entry.path().extension() == Some(OsStr::new("rs")) { + println!("File name processed is {:?}", entry); + file_entries.push(entry); + } + } + } + } + } + for file in file_entries { + let file_contents = fs::read_to_string(&file.path()).unwrap(); + + let mut stats_pointer = src_stats.lock().unwrap(); + for line in file_contents.lines() { + if line.len() == 0 { + stats_pointer.blanks += 1; + } else if line.starts_with("//") { + stats_pointer.comments += 1; + } else { + stats_pointer.loc += 1; + } + } + + stats_pointer.number_of_files += 1; + } + }); + child_handles.push(handle); + } + + for handle in child_handles { + handle.join().unwrap(); + } + println!("Source stats: {:?}", stats_counter.lock().unwrap()); +}