diff --git a/Chapter01/testing/src/lib.rs b/Chapter01/testing/src/lib.rs index b20c0c1..7153c2b 100644 --- a/Chapter01/testing/src/lib.rs +++ b/Chapter01/testing/src/lib.rs @@ -139,52 +139,6 @@ impl List where T: Sized + Clone { .value }) } - - - /// - /// Splits off and returns `n` nodes as a `List`. - /// - /// # Arguments - /// - /// `n: usize` - The number of elements after which to split the list. - /// - /// # Panics - /// - /// Panics when: - /// - The list is empty - /// - `n` is larger than the length - /// - /// # Example - /// - /// ``` - /// # use testing::List; - /// - /// let mut list = List::new_empty(); - /// list.append(12); - /// list.append(11); - /// list.append(10); - /// let mut list2 = list.split(1); - /// assert_eq!(list2.pop(), Some(12)); - /// assert_eq!(list.pop(), Some(11)); - /// assert_eq!(list.pop(), Some(10)); - /// ``` - /// - pub fn split(&mut self, n: usize) -> List { - - // Don't do this in real life. Use Results, Options, or anything that - // doesn't just kill the program - if self.length == 0 || n >= self.length - 1 { - panic!("That's not working"); - } - - let mut n = n; - let mut new_list = List::new_empty(); - while n > 0 { - new_list.append(self.pop().unwrap()); - n -= 1; - } - new_list - } } impl Drop for List where T: Clone + Sized { @@ -225,7 +179,7 @@ mod tests { list.append(1); list.append(1); list.append(1); - list.append(1); + list.append(1); list.append(1); assert_eq!(list.length, 5); } @@ -248,25 +202,4 @@ mod tests { assert_eq!(list.length, 0); assert_eq!(list.pop(), None); } - - #[test] - fn test_list_split() { - let mut list = List::new_empty(); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - assert_eq!(list.length, 5); - let list2 = list.split(3); - assert_eq!(list.length, 2); - assert_eq!(list2.length, 3); - } - - #[test] - #[should_panic] - fn test_list_split_panics() { - let mut list: List = List::new_empty(); - let _ = list.split(3); - } } diff --git a/Chapter01/traits/src/lib.rs b/Chapter01/traits/src/lib.rs index b35bca1..4b0d0b8 100644 --- a/Chapter01/traits/src/lib.rs +++ b/Chapter01/traits/src/lib.rs @@ -1,40 +1,38 @@ -use std::io::{Write, Read}; +use std::io::{Read, Write}; // Structs /// /// Configuration for our application -/// +/// pub struct Config { - values: Vec<(String, String)> + values: Vec<(String, String)>, } /// /// A service for managing a configuration -/// -pub struct KeyValueConfigService { - -} +/// +pub struct KeyValueConfigService {} // Traits /// -/// Provides a get() function to return valuse associated with +/// Provides a get() function to return values associated with /// the specified key. -/// +/// pub trait ValueGetter { fn get(&self, s: &str) -> Option; } /// /// Write a config -/// +/// pub trait ConfigWriter { fn write(&self, config: Config, to: &mut impl Write) -> std::io::Result<()>; } /// /// Read a config -/// +/// pub trait ConfigReader { fn read(&self, from: &mut impl Read) -> std::io::Result; } @@ -43,16 +41,13 @@ pub trait ConfigReader { impl Config { pub fn new(values: Vec<(String, String)>) -> Config { - Config { - values: values - } + Config { values: values } } } impl KeyValueConfigService { pub fn new() -> KeyValueConfigService { - KeyValueConfigService { - } + KeyValueConfigService {} } } @@ -72,34 +67,35 @@ impl ConfigReader for KeyValueConfigService { // chain iterators together and collect the results let values: Vec<(String, String)> = buffer - .split_terminator("\n") // split + .split_terminator("\n") // split .map(|line| line.trim()) // remove whitespace - .filter(|line| { // filter invalid lines - let pos = line.find("=") - .unwrap_or(0); + .filter(|line| { + // filter invalid lines + let pos = line.find("=").unwrap_or(0); pos > 0 && pos < line.len() - 1 }) - .map(|line| { // create a tuple from a line + .map(|line| { + // create a tuple from a line let parts = line.split("=").collect::>(); (parts[0].to_string(), parts[1].to_string()) }) - .collect(); // transform it into a vector + .collect(); // transform it into a vector Ok(Config::new(values)) } } impl ValueGetter for Config { fn get(&self, s: &str) -> Option { - self.values.iter() - .find_map(|tuple| if &tuple.0 == s { - Some(tuple.1.clone()) - } else { - None - }) + self.values.iter().find_map(|tuple| { + if &tuple.0 == s { + Some(tuple.1.clone()) + } else { + None + } + }) } } - #[cfg(test)] mod tests { use super::*; @@ -112,7 +108,6 @@ mod tests { assert_eq!(config.get("HELLO"), None); } - #[test] fn keyvalueconfigservice_write_config() { let config = Config::new(vec![("hello".to_string(), "world".to_string())]); @@ -121,20 +116,27 @@ mod tests { let mut target = vec![]; assert!(service.write(config, &mut target).is_ok()); - assert_eq!(String::from_utf8(target).unwrap(), "hello=world\n".to_string()); + assert_eq!( + String::from_utf8(target).unwrap(), + "hello=world\n".to_string() + ); } - #[test] + #[test] fn keyvalueconfigservice_read_config() { - let service = KeyValueConfigService::new(); let readable = &format!("{}\n{}", "hello=world", "a=b").into_bytes(); - - let config = service.read(&mut Cursor::new(readable)) + + let config = service + .read(&mut Cursor::new(readable)) .expect("Couldn't read from the vector"); - assert_eq!(config.values, vec![ + assert_eq!( + config.values, + vec![ ("hello".to_string(), "world".to_string()), - ("a".to_string(), "b".to_string())]); + ("a".to_string(), "b".to_string()) + ] + ); } -} \ No newline at end of file +} diff --git a/Chapter02/mut-sharing-ownership/src/lib.rs b/Chapter02/mut-sharing-ownership/src/lib.rs index 9360e02..f7eef54 100644 --- a/Chapter02/mut-sharing-ownership/src/lib.rs +++ b/Chapter02/mut-sharing-ownership/src/lib.rs @@ -1,7 +1,5 @@ #![feature(test)] -//pub mod list; - #[cfg(test)] mod tests { extern crate test; diff --git a/Chapter02/mut-sharing-ownership/src/list.rs b/Chapter02/mut-sharing-ownership/src/list.rs deleted file mode 100644 index 54eec7f..0000000 --- a/Chapter02/mut-sharing-ownership/src/list.rs +++ /dev/null @@ -1,261 +0,0 @@ -//! -//! A simple singly-linked list for the Rust-Cookbook by Packt Publishing. -//! -//! Recipes covered in this module: -//! - Documenting your code -//! - Testing your documentation -//! - Writing tests and benchmarks -//! - - -#![doc(html_logo_url = "https://blog.x5ff.xyz/img/main/logo.png", - test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] - -use std::cell::RefCell; -use std::rc::Rc; - -type Link = Option>>>; - -#[derive(Clone)] -struct Node where T: Sized + Clone { - value: T, - next: Link, -} - - -impl Node where T: Sized + Clone { - fn new(value: T) -> Rc>> { - Rc::new(RefCell::new(Node { - value: value, - next: None, - })) - } -} - -/// -/// A singly-linked list, with nodes allocated on the heap using `Rc`s and `RefCell`s. Here's an image illustrating a linked list: -/// -/// -/// ![](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg) -/// -/// *Found on https://en.wikipedia.org/wiki/Linked_list* -/// -/// # Usage -/// -/// ```ignore -/// let list = List::new_empty(); -/// ``` -/// -#[derive(Clone)] -pub struct List where T: Sized + Clone { - head: Link, - tail: Link, - - /// - /// The length of the list. - /// - pub length: usize, -} - -impl List where T: Sized + Clone { - - /// - /// Creates a new empty list. - /// - /// - /// # Example - /// - /// ``` - /// # use mut_sharing_ownership::list::List; - /// let list: List = List::new_empty(); - /// ``` - /// - pub fn new_empty() -> List { - List { head: None, tail: None, length: 0 } - } - - /// - /// Appends a node to the list at the end. - /// - /// - /// # Panics - /// - /// This never panics (probably). - /// - /// # Safety - /// - /// No unsafe code was used. - /// - /// # Example - /// - /// ``` - /// use mut_sharing_ownership::list::List; - /// - /// let mut list = List::new_empty(); - /// list.append(10); - /// ``` - /// - pub fn append(&mut self, value: T) { - let new = Node::new(value); - match self.tail.take() { - Some(old) => old.borrow_mut().next = Some(new.clone()), - None => self.head = Some(new.clone()) - }; - self.length += 1; - self.tail = Some(new); - } - - /// - /// Removes the list's head and returns the result. - /// - /// - /// # Panics - /// - /// Whenever when a node unexpectedly is `None` - /// - /// # Example - /// - /// ``` - /// # use mut_sharing_ownership::list::List; - /// - /// let mut list = List::new_empty(); - /// list.append(10); - /// assert_eq!(list.pop(), Some(10)); - /// ``` - /// - pub fn pop(&mut self) -> Option { - self.head.take().map(|head| { - if let Some(next) = head.borrow_mut().next.take() { - self.head = Some(next); - } else { - self.tail.take(); - } - self.length -= 1; - Rc::try_unwrap(head) - .ok() - .expect("Something is terribly wrong") - .into_inner() - .value - }) - } - - - /// - /// Splits off and returns `n` nodes as a `List`. - /// - /// # Arguments - /// - /// `n: usize` - The number of elements after which to split the list. - /// - /// # Panics - /// - /// Panics when: - /// - The list is empty - /// - `n` is larger than the length - /// - /// # Example - /// - /// ``` - /// # use mut_sharing_ownership::list::List; - /// - /// let mut list = List::new_empty(); - /// list.append(12); - /// list.append(11); - /// list.append(10); - /// let mut list2 = list.split(1); - /// assert_eq!(list2.pop(), Some(12)); - /// assert_eq!(list.pop(), Some(11)); - /// assert_eq!(list.pop(), Some(10)); - /// ``` - /// - pub fn split(&mut self, n: usize) -> List { - - // Don't do this in real life. Use Results, Options, or anything that - // doesn't just kill the program - if self.length == 0 || n >= self.length - 1 { - panic!("That's not working"); - } - - let mut n = n; - let mut new_list = List::new_empty(); - while n > 0 { - new_list.append(self.pop().unwrap()); - n -= 1; - } - new_list - } -} - -impl Drop for List where T: Clone + Sized { - - fn drop(&mut self) { - while self.length > 0 { - let n = self.pop(); - drop(n); - } - } -} - - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_list_new_empty() { - let mut list: List = List::new_empty(); - assert_eq!(list.length, 0); - assert_eq!(list.pop(), None); - } - - #[test] - fn test_list_append() { - let mut list = List::new_empty(); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - assert_eq!(list.length, 5); - } - - - #[test] - fn test_list_pop() { - let mut list = List::new_empty(); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - assert_eq!(list.length, 5); - assert_eq!(list.pop(), Some(1)); - assert_eq!(list.pop(), Some(1)); - assert_eq!(list.pop(), Some(1)); - assert_eq!(list.pop(), Some(1)); - assert_eq!(list.pop(), Some(1)); - assert_eq!(list.length, 0); - assert_eq!(list.pop(), None); - } - - #[test] - fn test_list_split() { - let mut list = List::new_empty(); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - list.append(1); - assert_eq!(list.length, 5); - let list2 = list.split(3); - assert_eq!(list.length, 2); - assert_eq!(list2.length, 3); - } - - #[test] - #[should_panic] - fn test_list_split_panics() { - let mut list: List = List::new_empty(); - let _ = list.split(3); - } -} diff --git a/Chapter10/rusty-ml/src/main.rs b/Chapter10/rusty-ml/src/main.rs index f3827fe..22aa719 100644 --- a/Chapter10/rusty-ml/src/main.rs +++ b/Chapter10/rusty-ml/src/main.rs @@ -1,4 +1,3 @@ -extern crate tch; use std::io::{Error, ErrorKind}; use std::path::Path; use std::time::Instant; @@ -118,14 +117,18 @@ fn predict_from_best() -> failure::Fallible<()> { let net = ConvNet::new(&vs.root(), 10); // restore weights - println!("Loading model weights from '{}'", model_weights_path.to_string_lossy()); + println!( + "Loading model weights from '{}'", + model_weights_path.to_string_lossy() + ); vs.load(model_weights_path)?; println!("Probabilities and predictions for 10 random images in the test set"); for (image_batch, label_batch) in m.test_iter(1).shuffle().to_device(vs.device()).take(10) { let raw_tensor = net .forward_t(&image_batch, false) - .softmax(-1).view(m.labels); + .softmax(-1) + .view(m.labels); let predicted_index: Vec = raw_tensor.argmax(0, false).into(); let probabilities: Vec = raw_tensor.into(); @@ -133,7 +136,7 @@ fn predict_from_best() -> failure::Fallible<()> { for p in probabilities { print!("{:.4} ", p); } - let label: Vec = label_batch.into(); + let label: Vec = label_batch.into(); println!("] predicted {}, was {}", predicted_index[0], label[0]); } Ok(())