├── 1-Basics_of_Code_Reuse ├── 2-Setting_up_the_Rust_Development_Environment │ └── hello_world.rs ├── 4-Loops_and_Iterators │ ├── 1-loop.rs │ ├── 2-for.rs │ ├── 3-IntoIterator.rs │ ├── 4-into_iter.rs │ └── 5-iter_and_iter_mut.rs ├── 5-Functional_programming_style_loops │ ├── 1-map.rs │ ├── 2-filter.rs │ ├── 3-closures.rs │ ├── 4-consuming_adaptors.rs │ ├── 5-chaining.rs │ ├── 6-lazy_evaluation.rs │ └── 7-infinite.rs └── 6-Functions_in_Rust │ ├── 1-functions.rs │ ├── 2-functions_with_paramters.rs │ ├── 3-function_move.rs │ └── 4-function_ref.rs ├── 2-Using_Generics_in_Rust ├── 1-Exploring_Generics │ ├── 1-shared-algorithm.rs │ └── 2-shared_struct.rs ├── 2-Using_Generic_Function_to_Reuse_Algorithms │ ├── 1-generic_function.rs │ └── 2-generic_function_with_trait_bound.rs ├── 3-Reuse_Structure_with_Structs_and_Enums │ ├── 1-generic_struct.rs │ ├── 2-generic_struct_multiple_generic.rs │ └── 3-generic_enum.rs ├── 4-Working_with_Generic_in_Struct_Methods │ ├── 1-impl.rs │ └── 2-impl_specific.rs └── 5-Generics_in_the_Rust_Standard_Library │ ├── 1-option │ ├── 1-option.rs │ ├── 2-result │ ├── 2-result.rs │ ├── 3-vec │ ├── 3-vec.rs │ ├── 4-wrappers │ └── 4-wrappers.rs ├── 3-Defining_Interfaces_with_Traits ├── 1-Exploring_Traits │ ├── 1-vehicle.rs │ └── 2-trait_bound.rs ├── 2-Using_Trait_Bounds_and_Trait_Objects_to_Communicate_Interfaces │ ├── 1-trait_bounds.rs │ ├── 2-trait_bounds_where.rs │ └── 3-trait_objects.rs ├── 3-Associaterd_Types_vs_Generics_Trait_Inheritence │ ├── 1-generic_implementation.rs │ ├── 2-associate_type.rs │ ├── 3-associate_type_restriction.rs │ └── 4-trait_inheritence.rs ├── 4-Exploring_Traits_Generics_and_Performance │ ├── 1-static_dispatch.rs │ ├── 2-static_dispatch_internal.rs │ ├── 3-dynamic_dispatch.rs │ └── 4-trait_object.rs ├── 5-Traits_in_the_Rust_Standard_Library_I │ ├── 1-PartialEq_before.rs │ ├── 2-PartialEq_implemented.rs │ ├── 3-Add.rs │ ├── 4-Drop.rs │ ├── 5-Fn_FnMut_FnOnce.rs │ └── 6-From_Into.rs └── 6-Traits_in_the_Rust_Standard_Library_II │ ├── 1-Copy_before.rs │ ├── 2-Copy.rs │ ├── 3-Copy_derive.rs │ ├── 4-Sized.rs │ ├── 5-Sized_and_trait_object.rs │ ├── 6-formatting.rs │ ├── 7-default.rs │ └── 8-default_enum.rs ├── 4-Hacking_the_Language_with_Marcos ├── 2-Use_Declarative_Macros_to_Write_Less_Code │ ├── 1-hello_world.rs │ ├── 2-vec.rs │ ├── 3-vec_macro.rs │ └── 4-macro_use.rs ├── 3-Using_Procedural_Macros_for_Custom_Derive │ ├── hello_macro │ │ ├── Cargo.toml │ │ ├── hello_macro_derive │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── src │ │ │ └── lib.rs │ └── hello_world │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── 4-Macros_in_the_Rust_Standard_Library_I │ ├── 1-vec.rs │ ├── 2-env.rs │ ├── 3-formatting.rs │ ├── 4-introspection.rs │ ├── 5-include.rs │ ├── external_rust_code.txt │ └── external_string.txt └── 5-Macros_in_the_Rust_Standard_Library_II │ ├── 1-cfg.rs │ ├── 2-try.rs │ ├── 3-panic.rs │ ├── 4-unimplemented.rs │ ├── 5-unreachable.rs │ └── 6-assertions.rs ├── 5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates ├── 1-Introducing_Crates │ ├── create_crates.sh │ ├── example-binary │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── example-library │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── 2-Using_Modules_to_Define_the_Structure_of_Crates │ ├── 1-simple_module.rs │ ├── 2-nested_modules.rs │ ├── 3-folder-structure │ │ ├── animal │ │ │ ├── cat.rs │ │ │ ├── dog.rs │ │ │ └── mod.rs │ │ └── lib.rs │ └── 4-pub.rs ├── 3-Using_a_Crate_With_Cargo_toml │ ├── animal │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── crates_io_example │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── github_example │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── local_example │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs └── 4-Publishing_to_crates_io │ └── publish-example │ ├── Cargo.toml │ └── src │ └── lib.rs ├── LICENSE └── README.md /1-Basics_of_Code_Reuse/2-Setting_up_the_Rust_Development_Environment/hello_world.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello World!"); 3 | } 4 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/4-Loops_and_Iterators/1-loop.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | 3 | /* 4 | loop { 5 | println!("I loop forever"); 6 | } 7 | */ 8 | 9 | let mut n = 0; 10 | while n < 10 { 11 | println!("{}", n); 12 | n = n + 1; 13 | // break and continue 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/4-Loops_and_Iterators/2-for.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | 3 | for element in 1..10 { 4 | println!("{}", element); 5 | } 6 | 7 | let mylist = [1, 2, 3, 4]; 8 | 9 | for element in mylist.into_iter() { 10 | println!("{}", element); 11 | } 12 | 13 | /* 14 | for element in mylist { 15 | // ^^^ Not an iterator 16 | println!("{}", element); 17 | } 18 | */ 19 | } 20 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/4-Loops_and_Iterators/3-IntoIterator.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mylist = vec!(1, 2, 3, 4); 3 | 4 | for element in mylist { 5 | // .into_iter() can be omitted 6 | println!("{}", element); 7 | } 8 | 9 | /* 10 | let mut iter = IntoIterator::into_iter(mylist); 11 | loop { 12 | match iter.next() { 13 | Some(x) => { 14 | println!("{}", x); 15 | }, 16 | None => { break } 17 | } 18 | } 19 | */ 20 | } 21 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/4-Loops_and_Iterators/4-into_iter.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mylist = vec!(1, 2, 3, 4); 3 | 4 | for element in mylist.into_iter() { 5 | println!("{}", element); 6 | } 7 | 8 | println!("{}", mylist[0]); 9 | // ^^^^^^ value used here after move 10 | 11 | } 12 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/4-Loops_and_Iterators/5-iter_and_iter_mut.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut mylist = vec!(1, 2, 3, 4); 3 | 4 | for element in mylist.iter() { 5 | // &element is &i32 6 | println!("{}", *element); 7 | } 8 | 9 | println!("{}", mylist[0]); 10 | 11 | for element in mylist.iter_mut() { 12 | // element is &mut i32 13 | *element = *element + 1; 14 | println!("{}", *element); 15 | } 16 | 17 | println!("{}", mylist[0]); 18 | } 19 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/1-map.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = vec![1,2,3,4]; 3 | 4 | let plus_one = numbers.iter().map(|x| x + 1); 5 | 6 | plus_one.for_each(|x| println!("{}", x)); 7 | } 8 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/2-filter.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = vec![1, 2, 3, 4]; 3 | 4 | let larger_then_two = numbers.into_iter().filter(|&x| x > 2); 5 | // [ 1, 2, 3, 4] 6 | // [false, false, true, true] 7 | // => [3, 4] 8 | 9 | larger_then_two.for_each(|x| println!("{}", x)); 10 | } 11 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/3-closures.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = vec![1, 2, 3, 4]; 3 | 4 | let y = 1; 5 | 6 | let plus_one = numbers.iter().map(|x| x + y); 7 | 8 | plus_one.for_each(|x| println!("{}", x)); 9 | } 10 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/4-consuming_adaptors.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = vec![1, 2, 3, 4]; 3 | 4 | let sum:i32 = numbers.iter().sum(); 5 | println!("Sum: {}", sum); 6 | 7 | let max:&i32 = numbers.iter().max().unwrap(); 8 | println!("Max: {}", max); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/5-chaining.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = vec![1, 2, 3, 4]; 3 | 4 | let squared_sum:i32 = numbers.iter() 5 | .map(|x| x * x) // squared 6 | .sum(); 7 | 8 | println!("Squared sum: {}", squared_sum); 9 | } 10 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/6-lazy_evaluation.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let numbers = vec![1, 2, 3, 4]; 3 | 4 | numbers.iter().map(|x| x + 1); 5 | 6 | /* 7 | let plus_one_iter = numbers.iter().map(|x| x + 1); 8 | println!("{:?}", plus_one_iter); 9 | 10 | let plus_one:Vec = plus_one_iter.collect(); 11 | println!("{:?}", plus_one); 12 | */ 13 | } 14 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/5-Functional_programming_style_loops/7-infinite.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | 3 | let numbers:Vec = (1..) // 1 to inifintiy 4 | .map(|x| x + 1) // [2, 3, 4, 5, 6, ...] 5 | .map(|x| x * x) // [4, 9, 16, 25, 36, ...] 6 | .take(5) // "take" the first five 7 | .collect(); // collect them into a vec 8 | 9 | println!("{:?}", numbers); 10 | } 11 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/6-Functions_in_Rust/1-functions.rs: -------------------------------------------------------------------------------- 1 | fn my_function() { 2 | println!("Hello world"); 3 | } 4 | 5 | fn main() { 6 | my_function(); 7 | my_function(); 8 | my_function(); 9 | } 10 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/6-Functions_in_Rust/2-functions_with_paramters.rs: -------------------------------------------------------------------------------- 1 | fn my_function_i32(msg: i32) { 2 | println!("Hello world {}", msg); 3 | } 4 | 5 | fn my_function_str(msg: &str) { 6 | println!("Hello world {}", msg); 7 | } 8 | 9 | fn main() { 10 | my_function_i32(42); 11 | my_function_str("Morty"); 12 | } 13 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/6-Functions_in_Rust/3-function_move.rs: -------------------------------------------------------------------------------- 1 | fn consuming_print(numbers: Vec) { 2 | // ------- value moved into the function 3 | for number in numbers { 4 | println!("{}", number); 5 | } 6 | } 7 | 8 | fn main() { 9 | let numbers = vec!(1, 2, 3); 10 | consuming_print(numbers); 11 | // ------- value moved here 12 | println!("{}", numbers[0]); 13 | // ^^^^^^^ value used here after move 14 | 15 | } 16 | -------------------------------------------------------------------------------- /1-Basics_of_Code_Reuse/6-Functions_in_Rust/4-function_ref.rs: -------------------------------------------------------------------------------- 1 | fn consuming_print(numbers: &Vec) { 2 | // ^ use reference instead 3 | for number in numbers { 4 | println!("{}", number); 5 | } 6 | } 7 | 8 | fn main() { 9 | let numbers = vec!(1, 2, 3); 10 | consuming_print(&numbers); 11 | // ^ pass a reference to the Vec 12 | println!("{}", numbers[0]); 13 | // ^^^^^^^ not moved, we can use it again 14 | 15 | } 16 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/1-Exploring_Generics/1-shared-algorithm.rs: -------------------------------------------------------------------------------- 1 | fn largest_i32(list: &[i32]) -> i32 { 2 | let mut largest = list[0]; 3 | 4 | for &item in list.iter() { 5 | if item > largest { 6 | largest = item; 7 | } 8 | } 9 | largest 10 | } 11 | 12 | fn largest_char(list: &[char]) -> char { 13 | let mut largest = list[0]; 14 | 15 | for &item in list.iter() { 16 | if item > largest { 17 | largest = item; 18 | } 19 | } 20 | largest 21 | } 22 | 23 | fn main() { 24 | let number_list = vec![34, 50, 25, 100, 65]; 25 | 26 | let result = largest_i32(&number_list); 27 | println!("The largest number is {}", result); 28 | 29 | let char_list = vec!['y', 'm', 'a', 'q']; 30 | 31 | let result = largest_char(&char_list); 32 | println!("The largest char is {}", result); 33 | } 34 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/1-Exploring_Generics/2-shared_struct.rs: -------------------------------------------------------------------------------- 1 | struct PointInteger { 2 | x: i32, 3 | y: i32, 4 | } 5 | 6 | struct PointFloat { 7 | x: f32, 8 | y: f32, 9 | } 10 | 11 | fn main() { 12 | let integer = PointInteger { x: 5, y: 10 }; 13 | let float = PointFloat { x: 1.0, y: 4.0 }; 14 | } 15 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/2-Using_Generic_Function_to_Reuse_Algorithms/1-generic_function.rs: -------------------------------------------------------------------------------- 1 | fn largest(list: &[T]) -> T { 2 | let mut largest = list[0]; 3 | 4 | for &item in list.iter() { 5 | if item > largest { 6 | largest = item; 7 | } 8 | } 9 | largest 10 | } 11 | 12 | fn main() { 13 | let number_list = vec![34, 50, 25, 100, 65]; 14 | 15 | // T is explicitly specified 16 | let result = largest::(&number_list); 17 | println!("The largest number is {}", result); 18 | 19 | let char_list = vec!['y', 'm', 'a', 'q']; 20 | 21 | // T can be inferred by the compiler 22 | let result = largest(&char_list); 23 | println!("The largest char is {}", result); 24 | } 25 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/2-Using_Generic_Function_to_Reuse_Algorithms/2-generic_function_with_trait_bound.rs: -------------------------------------------------------------------------------- 1 | fn largest(list: &[T]) -> T { 2 | let mut largest = list[0]; 3 | 4 | for &item in list.iter() { 5 | if item > largest { 6 | largest = item; 7 | } 8 | } 9 | 10 | largest 11 | } 12 | 13 | fn main() { 14 | let number_list = vec![34, 50, 25, 100, 65]; 15 | 16 | // T is explicitly specified 17 | let result = largest::(&number_list); 18 | println!("The largest number is {}", result); 19 | 20 | let char_list = vec!['y', 'm', 'a', 'q']; 21 | 22 | // T can be inferred by the compiler 23 | let result = largest(&char_list); 24 | println!("The largest char is {}", result); 25 | } 26 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/3-Reuse_Structure_with_Structs_and_Enums/1-generic_struct.rs: -------------------------------------------------------------------------------- 1 | struct Point { 2 | x: T, 3 | y: T, 4 | } 5 | 6 | fn main() { 7 | let integer = Point { x: 5, y: 10 }; 8 | let float = Point { x: 1.0, y: 4.0 }; 9 | // let mixed = Point { x: 5, y: 4.0 }; // Won't compile 10 | } 11 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/3-Reuse_Structure_with_Structs_and_Enums/2-generic_struct_multiple_generic.rs: -------------------------------------------------------------------------------- 1 | struct Point { 2 | x: T, 3 | y: U, 4 | } 5 | 6 | fn main() { 7 | let integer = Point { x: 5, y: 10 }; 8 | let float = Point { x: 1.0, y: 4.0 }; 9 | let mixed = Point { x: 5, y: 4.0 }; 10 | } 11 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/3-Reuse_Structure_with_Structs_and_Enums/3-generic_enum.rs: -------------------------------------------------------------------------------- 1 | enum Option { 2 | Some(T), 3 | None, 4 | } 5 | 6 | fn main() { 7 | let some_integer = Option::Some(42); 8 | let some_float = Option::Some(3.14); 9 | let none: Option = Option::None; 10 | } 11 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/4-Working_with_Generic_in_Struct_Methods/1-impl.rs: -------------------------------------------------------------------------------- 1 | struct Point { 2 | x: T, 3 | y: T, 4 | } 5 | 6 | 7 | impl Point { 8 | // ^^^ ^^^ 9 | fn get_x(&self) -> &T { 10 | &self.x 11 | } 12 | } 13 | 14 | fn main() { 15 | let p = Point { x: 5, y: 10 }; 16 | 17 | println!("p.x = {}", p.get_x()); 18 | } 19 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/4-Working_with_Generic_in_Struct_Methods/2-impl_specific.rs: -------------------------------------------------------------------------------- 1 | struct Point { 2 | x: T, 3 | y: T, 4 | } 5 | 6 | impl Point { 7 | // ^ notice that there is no here 8 | fn get_x(&self) -> &i32 { 9 | &self.x 10 | } 11 | } 12 | 13 | fn main() { 14 | let p = Point { x: 5, y: 10 }; 15 | println!("p.x = {}", p.get_x()); // integer 16 | 17 | let p = Point { x: 5.0, y: 10.0 }; 18 | println!("p.x = {}", p.get_x()); // float 19 | } 20 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/1-option: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Building-Reusable-Code-with-Rust/13b1f7d4099ce7bca8332f05a5c2701187a470bf/2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/1-option -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/1-option.rs: -------------------------------------------------------------------------------- 1 | /* 2 | enum Option { 3 | Some, 4 | None, 5 | } 6 | */ 7 | 8 | fn first_element(list: Vec) -> Option { 9 | if list.len() == 0 { 10 | None 11 | } else { 12 | Some(list[0]) 13 | } 14 | } 15 | 16 | fn main() { 17 | let list = vec!(1, 2, 3, 4); 18 | 19 | match first_element(list) { 20 | None => println!("Empty list!"), 21 | Some(x) => println!("The first element is {}", x), 22 | } 23 | 24 | match first_element(Vec::new()) { 25 | None => println!("Empty list!"), 26 | Some(x) => println!("The first element is {}", x), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/2-result: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Building-Reusable-Code-with-Rust/13b1f7d4099ce7bca8332f05a5c2701187a470bf/2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/2-result -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/2-result.rs: -------------------------------------------------------------------------------- 1 | /* 2 | enum Result { 3 | Ok(T), 4 | Err(E), 5 | } 6 | */ 7 | 8 | fn get_middle(list: Vec) -> Result { 9 | match list.len() { 10 | 0 => Err("empty list"), 11 | x if x % 2 == 0 => Err("list has even number of elements"), 12 | _ => Ok(list[list.len() / 2]), 13 | } 14 | } 15 | 16 | fn main() { 17 | println!("{:?}", get_middle(vec![1, 2, 3])); 18 | println!("{:?}", get_middle(vec![1, 2, 3, 4])); 19 | println!("{:?}", get_middle(Vec::new())); 20 | } 21 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/3-vec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Building-Reusable-Code-with-Rust/13b1f7d4099ce7bca8332f05a5c2701187a470bf/2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/3-vec -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/3-vec.rs: -------------------------------------------------------------------------------- 1 | /* 2 | impl Vec { 3 | pub const fn new() -> Vec 4 | } 5 | */ 6 | fn main() { 7 | let mut list: Vec = Vec::new(); 8 | //let mut list = Vec::new(); // Type inference 9 | //let mut list = Vec::::new(); // turbofish ::<> 10 | 11 | list.push(1); 12 | list.push(2); 13 | list.push(3); 14 | 15 | println!("{:?}", list); 16 | } 17 | 18 | // See also: std::collections 19 | // https://doc.rust-lang.org/std/collections/index.html 20 | 21 | // Sequences: Vec, VecDeque, LinkedList 22 | // Maps: HashMap, BTreeMap 23 | // Sets: HashSet, BTreeSet 24 | // Misc: BinaryHeap 25 | -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/4-wrappers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Building-Reusable-Code-with-Rust/13b1f7d4099ce7bca8332f05a5c2701187a470bf/2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/4-wrappers -------------------------------------------------------------------------------- /2-Using_Generics_in_Rust/5-Generics_in_the_Rust_Standard_Library/4-wrappers.rs: -------------------------------------------------------------------------------- 1 | use std::rc::Rc; 2 | use std::cell::{Cell, RefCell}; 3 | use std::sync::{Arc, Mutex, RwLock}; 4 | 5 | fn main() { 6 | // Heap allocated pointers 7 | let mybox: Box = Box::new(42); // heap allocated memory 8 | let myrc: Rc = Rc::new(42); // reference-counted 9 | 10 | // Cell with internal mutability 11 | let mycell: Cell = Cell::new(42); 12 | // mycell.set(0); 13 | // mycell.get(); 14 | let myrefcell: RefCell = RefCell::new(42); // with read-write lock 15 | // myrefcell.borrow() 16 | // myrefcell.borrow_mut() 17 | 18 | // Thread-safe version 19 | let myarc: Arc = Arc::new(42); // atomic reference counted Rc 20 | let mymutex: Mutex = Mutex::new(42); 21 | // mutex.lock() 22 | let myrwlock: RwLock = RwLock::new(42); 23 | // myrwlock.lock() 24 | 25 | // composition examples: 26 | // Rc> 27 | // Rc>> 28 | 29 | // Reference: 30 | // https://doc.rust-lang.org/book/first-edition/choosing-your-guarantees.html 31 | } 32 | 33 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/1-Exploring_Traits/1-vehicle.rs: -------------------------------------------------------------------------------- 1 | trait Vehicle { 2 | fn new(name: &'static str) -> Self; // static method 3 | fn move(&self) -> (); // instance method 4 | fn to_string(&self) { 5 | println!("vehicle {}", self.name) // default implementation 6 | } 7 | } 8 | 9 | struct Airplane { name: &'static str } 10 | struct Bicycle { name: &'static str } 11 | struct Car { name: &'static str } 12 | 13 | impl Vehicle for Airplane { 14 | fn new(name: &'static str) -> Self { 15 | Airplane { name: name } 16 | } 17 | fn move(&self) { 18 | self.fly(); 19 | } 20 | } 21 | 22 | impl Vehicle for Bicycle { 23 | fn new(name: &'static str) -> Self { 24 | Bicycle { name: name } 25 | } 26 | fn move(&self) { 27 | self.pedal(); 28 | } 29 | } 30 | 31 | impl Vehicle for Car { 32 | fn new(name: &'static str) -> Self { 33 | Car { name: name } 34 | } 35 | fn move(&self) { 36 | self.drive(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/1-Exploring_Traits/2-trait_bound.rs: -------------------------------------------------------------------------------- 1 | fn from_amsterdam_to_paris(vehicle: T) { 2 | // ^-------- Trait bound 3 | while (location_of(vehicle) != "Paris") { 4 | vehicle.move() 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/2-Using_Trait_Bounds_and_Trait_Objects_to_Communicate_Interfaces/1-trait_bounds.rs: -------------------------------------------------------------------------------- 1 | fn largest(list: &[T]) -> T { 2 | let mut largest = list[0]; 3 | // ^------ Copy 4 | for &item in list.iter() { 5 | // ^---- Copy 6 | if item > largest { 7 | // ^ PartialOrd::gt() 8 | largest = item; 9 | } 10 | } 11 | 12 | largest 13 | } 14 | 15 | // fn largest(list: &[T]) -> T 16 | // where T: PartialOrd + Copy { 17 | // // function body 18 | // } 19 | 20 | fn main() { 21 | let number_list = vec![34, 50, 25, 100, 65]; 22 | 23 | // T is explicitly specified 24 | let result = largest::(&number_list); 25 | println!("The largest number is {}", result); 26 | 27 | let char_list = vec!['y', 'm', 'a', 'q']; 28 | 29 | // T can be inferred by the compiler 30 | let result = largest(&char_list); 31 | println!("The largest char is {}", result); 32 | } 33 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/2-Using_Trait_Bounds_and_Trait_Objects_to_Communicate_Interfaces/2-trait_bounds_where.rs: -------------------------------------------------------------------------------- 1 | fn largest(list: &[T]) -> T 2 | where T: PartialOrd + Copy { // <= where 3 | let mut largest = list[0]; 4 | // ^------ Copy 5 | for &item in list.iter() { 6 | // ^---- Copy 7 | if item > largest { 8 | // ^ PartialOrd::gt() 9 | largest = item; 10 | } 11 | } 12 | 13 | largest 14 | } 15 | 16 | // } 17 | 18 | fn main() { 19 | let number_list = vec![34, 50, 25, 100, 65]; 20 | 21 | // T is explicitly specified 22 | let result = largest::(&number_list); 23 | println!("The largest number is {}", result); 24 | 25 | let char_list = vec!['y', 'm', 'a', 'q']; 26 | 27 | // T can be inferred by the compiler 28 | let result = largest(&char_list); 29 | println!("The largest char is {}", result); 30 | } 31 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/2-Using_Trait_Bounds_and_Trait_Objects_to_Communicate_Interfaces/3-trait_objects.rs: -------------------------------------------------------------------------------- 1 | trait NoisyAnimal { 2 | fn make_noise(&self) -> &'static str; 3 | } 4 | 5 | 6 | struct Cat {} 7 | impl NoisyAnimal for Cat { 8 | fn make_noise(&self) -> &'static str { 9 | "meow" 10 | } 11 | } 12 | 13 | struct Dog {} 14 | impl NoisyAnimal for Dog { 15 | fn make_noise(&self) -> &'static str{ 16 | "woof" 17 | } 18 | } 19 | 20 | fn make_noises(animals: Vec>) { 21 | // ^---------- Trait Object 22 | for animal in animals.iter() { 23 | println!("{}", animal.make_noise()); 24 | } 25 | } 26 | 27 | fn main() { 28 | let animals: Vec> = vec![ 29 | Box::new(Dog{}), 30 | Box::new(Cat{}), 31 | ]; 32 | make_noises(animals); 33 | } 34 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/3-Associaterd_Types_vs_Generics_Trait_Inheritence/1-generic_implementation.rs: -------------------------------------------------------------------------------- 1 | trait Iterator { 2 | fn next(&mut self) -> Option; 3 | } 4 | 5 | struct Counter; 6 | 7 | impl Iterator for Counter { 8 | fn next(&mut self) -> Option { 9 | // Implement here 10 | } 11 | } 12 | 13 | impl Iterator for Counter { 14 | fn next(&mut self) -> Option { 15 | // Implement here 16 | } 17 | } 18 | 19 | fn main() { 20 | let mut counter = Counter {}; 21 | 22 | let n_int: Option = counter.next(); 23 | println!("{:?}", n_int); 24 | 25 | let n_string: Option = counter.next(); 26 | println!("{:?}", n_string); 27 | 28 | let n_unknown = counter.next(); 29 | println!("{:?}", n_unknown); 30 | } 31 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/3-Associaterd_Types_vs_Generics_Trait_Inheritence/2-associate_type.rs: -------------------------------------------------------------------------------- 1 | trait Iterator { 2 | type Item; // <= associated type 3 | 4 | fn next(&mut self) -> Option; // <= used here 5 | } 6 | 7 | struct Counter; 8 | 9 | impl Iterator for Counter { 10 | type Item = u32; 11 | 12 | fn next(&mut self) -> Option { 13 | // Just for demo 14 | Some(42) 15 | } 16 | } 17 | 18 | impl Iterator for Counter { 19 | type Item = String; 20 | 21 | fn next(&mut self) -> Option { 22 | // Just for demo 23 | Some("42".to_string()) 24 | } 25 | } 26 | 27 | fn main() { 28 | let mut counter = Counter {}; 29 | 30 | let n = counter.next(); 31 | println!("{:?}", n); 32 | } 33 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/3-Associaterd_Types_vs_Generics_Trait_Inheritence/3-associate_type_restriction.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | trait Iterator { 4 | type Item: fmt::Display; // <= associated type 5 | 6 | fn next(&mut self) -> Option; // <= used here 7 | } 8 | 9 | struct Counter; 10 | 11 | impl Iterator for Counter { 12 | type Item = u32; 13 | 14 | fn next(&mut self) -> Option { 15 | // Just for demo 16 | Some(42) 17 | } 18 | } 19 | 20 | /* 21 | struct NoDisplayType; // Type without fmt::Display can't be used 22 | 23 | impl Iterator for Counter { 24 | type Item = NoDisplayType; // Not OK here 25 | fn next(&mut self) -> Option { 26 | // Just for demo 27 | Some("42".to_string()) 28 | } 29 | } 30 | */ 31 | 32 | fn main() { 33 | let mut counter = Counter {}; 34 | 35 | let n = counter.next(); 36 | println!("{}", n.unwrap()); 37 | // ^- using the default formatter requires fmt::Display 38 | } 39 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/3-Associaterd_Types_vs_Generics_Trait_Inheritence/4-trait_inheritence.rs: -------------------------------------------------------------------------------- 1 | trait X {} 2 | trait Y {} 3 | trait Z: X + Y {} 4 | 5 | struct A; 6 | 7 | //impl X for A {} 8 | //impl Y for A {} 9 | impl Z for A {} 10 | 11 | fn main() {} 12 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/4-Exploring_Traits_Generics_and_Performance/1-static_dispatch.rs: -------------------------------------------------------------------------------- 1 | trait ShowMyself { 2 | fn show(&self) -> String; 3 | } 4 | 5 | impl ShowMyself for u32 { 6 | fn show(&self) -> String { 7 | format!("I'm u32 {}", *self) 8 | } 9 | } 10 | 11 | impl ShowMyself for String { 12 | fn show(&self) -> String { 13 | format!("I'm String {}", *self) 14 | } 15 | } 16 | 17 | fn show_myself(x: T) { 18 | println!("{}", x.show()); 19 | } 20 | 21 | fn main() { 22 | let x: u32 = 42; 23 | let y: String = "Hello World".to_string(); 24 | 25 | show_myself(x); 26 | show_myself(y); 27 | } 28 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/4-Exploring_Traits_Generics_and_Performance/2-static_dispatch_internal.rs: -------------------------------------------------------------------------------- 1 | trait ShowMyself { 2 | fn show(&self) -> String; 3 | } 4 | 5 | impl ShowMyself for u32 { 6 | fn show(&self) -> String { 7 | format!("I'm u32 {}", *self) 8 | } 9 | } 10 | 11 | impl ShowMyself for String { 12 | fn show(&self) -> String { 13 | format!("I'm String {}", *self) 14 | } 15 | } 16 | 17 | /* 18 | fn show_myself(x: T) { 19 | println!("{}", x.show()); 20 | } 21 | */ 22 | 23 | // Compiler "expands" the function into all implementations 24 | fn show_myself_u32(x: u32) { 25 | println!("{}", x.show()); 26 | } 27 | 28 | fn show_myself_string(x: String) { 29 | println!("{}", x.show()); 30 | } 31 | 32 | fn main() { 33 | let x: u32 = 42; 34 | let y: String = "Hello World".to_string(); 35 | 36 | // Compiler chooses the right implementation and inline it 37 | show_myself_u32(x); 38 | show_myself_string(y); 39 | } 40 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/4-Exploring_Traits_Generics_and_Performance/3-dynamic_dispatch.rs: -------------------------------------------------------------------------------- 1 | trait ShowMyself { 2 | fn show(&self) -> String; 3 | } 4 | 5 | impl ShowMyself for u32 { 6 | fn show(&self) -> String { 7 | format!("I'm u32 {}", *self) 8 | } 9 | } 10 | 11 | impl ShowMyself for String { 12 | fn show(&self) -> String { 13 | format!("I'm String {}", *self) 14 | } 15 | } 16 | 17 | fn show_myself(x: &ShowMyself) { 18 | println!("{}", x.show()); 19 | } 20 | 21 | fn main() { 22 | let x: &ShowMyself = &42; 23 | let y = &"Hello World".to_string() as &ShowMyself; 24 | 25 | show_myself(x); 26 | show_myself(y); 27 | } 28 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/4-Exploring_Traits_Generics_and_Performance/4-trait_object.rs: -------------------------------------------------------------------------------- 1 | pub struct TraitObject { 2 | pub data: *mut (), // point to the concrete type data 3 | pub vtable: *mut (), // list of function pointers 4 | } 5 | // https://doc.rust-lang.org/std/raw/struct.TraitObject.html 6 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/5-Traits_in_the_Rust_Standard_Library_I/1-PartialEq_before.rs: -------------------------------------------------------------------------------- 1 | // '==' and '!=' operator: PartialEq 2 | 3 | struct Point { 4 | x: i32, 5 | y: i32, 6 | } 7 | 8 | fn main() { 9 | let p1 = Point { x: 10, y: 10 }; 10 | let p2 = Point { x: 10, y: 10 }; 11 | 12 | println!("p1 == p2: {}", p1 == p2); 13 | // ^- How does the equal operator work? 14 | } 15 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/5-Traits_in_the_Rust_Standard_Library_I/2-PartialEq_implemented.rs: -------------------------------------------------------------------------------- 1 | // '==' and '!=' operator: PartialEq 2 | use std::cmp::PartialEq; 3 | 4 | struct Point { 5 | x: i32, 6 | y: i32, 7 | } 8 | 9 | impl PartialEq for Point { 10 | fn eq(&self, other: &Point) -> bool { 11 | (self.x == other.x) && (self.y == other.y) 12 | } 13 | } 14 | 15 | fn main() { 16 | let p1 = Point { x: 10, y: 10 }; 17 | let p2 = Point { x: 10, y: 10 }; 18 | 19 | println!("p1 == p2: {}", p1 == p2); 20 | 21 | let p3 = Point { x: 20, y: 30 }; 22 | 23 | println!("p1 != p3: {}", p1 != p3); 24 | } 25 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/5-Traits_in_the_Rust_Standard_Library_I/3-Add.rs: -------------------------------------------------------------------------------- 1 | pub trait Add { 2 | // ^----- Default generic 3 | type Output; // Associate type 4 | fn add(self, rhs: RHS) -> Self::Output; 5 | } 6 | 7 | struct Point { 8 | x: i32, 9 | y: i32, 10 | 11 | } 12 | 13 | impl Add for Point { // RHS is left as default 14 | type Output = Point; // Associate type 15 | 16 | fn add(self, other: Point) -> Point { 17 | Point { 18 | x: self.x + other.x, 19 | y: self.y + other.y, 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/5-Traits_in_the_Rust_Standard_Library_I/4-Drop.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Drop; 2 | 3 | 4 | struct MyType; 5 | 6 | impl Drop for MyType { 7 | fn drop(&mut self) { 8 | println!("Dropping"); 9 | // Do some cleanup here 10 | } 11 | } 12 | 13 | fn main() { 14 | println!("Declaring"); 15 | let x = MyType; 16 | println!("About to exit main"); 17 | } 18 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/5-Traits_in_the_Rust_Standard_Library_I/5-Fn_FnMut_FnOnce.rs: -------------------------------------------------------------------------------- 1 | fn consuming_call(func: F) 2 | where F: FnOnce() -> String // F is a FnOnce 3 | { 4 | println!("Consumed {}", func()) 5 | // ^----- calling the F 6 | } 7 | 8 | fn main() { 9 | 10 | let x = String::from("hello"); 11 | 12 | let return_x = move || x; // A closure that consumes x and returns it directly 13 | // FnOnce are automatically implemented for clouse that might consume captured variables 14 | consuming_call(return_x) 15 | } 16 | 17 | /* 18 | 19 | pub trait FnOnce { 20 | type Output; 21 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; 22 | // ^--- may consume it, can only be called once 23 | } 24 | 25 | pub trait FnMut: FnOnce { 26 | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; 27 | // ^-------- may mutate it, 28 | // but safe to call multiple times 29 | } 30 | 31 | pub trait Fn: FnMut { 32 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; 33 | // ^---- Safe to call multiple times 34 | // without mutating state 35 | } 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/5-Traits_in_the_Rust_Standard_Library_I/6-From_Into.rs: -------------------------------------------------------------------------------- 1 | // Make MyNumber and i32 inter-convertible 2 | 3 | #[derive(Debug)] 4 | struct MyNumber { 5 | value: i32, 6 | } 7 | 8 | // from i32 to MyNumber 9 | impl From for MyNumber { 10 | fn from(number: i32) -> Self { 11 | MyNumber { value: number } 12 | } 13 | } 14 | 15 | // When we implments From, we get the corresponding 16 | // "impl Into for i32" for free 17 | 18 | fn main() { 19 | // Convert an i32 into MyNumber using From 20 | let num1 = MyNumber::from(42i32); 21 | 22 | // Convert an i32 into MyNumber using Into 23 | let num2: MyNumber = 42i32.into(); 24 | 25 | println!("{:?}", num1); 26 | println!("{:?}", num2); 27 | } 28 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/1-Copy_before.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] // ignore this for now 2 | struct MyStruct; 3 | 4 | #[allow(unused_variables)] 5 | pub fn main() { 6 | let x = MyStruct {}; 7 | let y = x; 8 | // x has moved into y, x is not usable anymore 9 | println!("{:?}", x); 10 | } 11 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/2-Copy.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] // ignore this for now 2 | struct MyStruct; 3 | 4 | // pub trait Copy: Clone {} // Clone is a supertrait of Copy 5 | 6 | // Copy is trivial bitwise copy, can't be overloaded 7 | // Notice it's empty, this is what we called marker trait 8 | impl Copy for MyStruct {} 9 | 10 | // Clone is explicit memory copy, usually expensive 11 | impl Clone for MyStruct { 12 | fn clone(&self) -> MyStruct { 13 | *self 14 | } 15 | } 16 | 17 | #[allow(unused_variables)] 18 | pub fn main() { 19 | let x = MyStruct {}; 20 | let y = x; 21 | // y is a copy of x, x is not moved 22 | println!("{:?}", x); 23 | } 24 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/3-Copy_derive.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Copy, Clone)] // Automatically implmeneted by the compiler 2 | struct MyStruct; 3 | 4 | #[allow(unused_variables)] 5 | pub fn main() { 6 | let x = MyStruct {}; 7 | let y = x; 8 | // y is a copy of x, x is not moved 9 | println!("{:?}", x); 10 | } 11 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/4-Sized.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | struct HasSizedT(T); // T: Sized by default 4 | struct NotSizedT(T); 5 | 6 | // [i32] is not Sized 7 | struct NoOK(HasSizedT<[i32]>); 8 | // ^^^^^^^^^^^^^^^^^ `[i32]` does not have a constant size known at compile-time 9 | 10 | struct OK(NotSizedT<[i32]>); 11 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/5-Sized_and_trait_object.rs: -------------------------------------------------------------------------------- 1 | trait NoisyAnimal: Sized { 2 | // ^---- Sized trait can't be made into a trait object 3 | fn make_noise(&self) -> &'static str; 4 | } 5 | 6 | 7 | struct Cat {} 8 | impl NoisyAnimal for Cat { 9 | fn make_noise(&self) -> &'static str { 10 | "meow" 11 | } 12 | } 13 | 14 | struct Dog {} 15 | impl NoisyAnimal for Dog { 16 | fn make_noise(&self) -> &'static str{ 17 | "woof" 18 | } 19 | } 20 | 21 | fn make_noises(animals: Vec>) { 22 | // ^---------- Trait Object 23 | for animal in animals.iter() { 24 | println!("{}", animal.make_noise()); 25 | } 26 | } 27 | 28 | fn main() { 29 | let animals: Vec> = vec![ 30 | Box::new(Dog{}), 31 | Box::new(Cat{}), 32 | ]; 33 | make_noises(animals); 34 | } 35 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/6-formatting.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{Display, Formatter, Result}; 2 | 3 | #[derive(Debug)] 4 | struct Cat { 5 | name: &'static str, 6 | breed: &'static str, 7 | age: u8, 8 | } 9 | 10 | impl Display for Cat { 11 | fn fmt(&self, f: &mut Formatter) -> Result { 12 | write!(f, 13 | "{} the {}-years old {} cat", 14 | self.name, 15 | self.age, 16 | self.breed 17 | ) 18 | } 19 | } 20 | 21 | fn main() { 22 | let felix = Cat { 23 | name: "Felix", 24 | breed: "Scottish Fold", 25 | age: 4 26 | }; 27 | 28 | let sinba = Cat { 29 | name: "Sinba", 30 | breed: "Lion", 31 | age: 2 32 | }; 33 | 34 | // Display 35 | println!("{}", felix); 36 | println!("{}", sinba); 37 | 38 | // Debug 39 | println!("{:?}", felix); 40 | println!("{:?}", sinba); 41 | 42 | // Debug, pretty-print 43 | println!("{:#?}", felix); 44 | println!("{:#?}", sinba); 45 | } 46 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/7-default.rs: -------------------------------------------------------------------------------- 1 | #[derive(Default, Debug)] 2 | struct MyData { 3 | int_field: i32, 4 | float_field: f32, 5 | } 6 | 7 | fn main() { 8 | // Use default values for all the fields 9 | let data1: MyData = Default::default(); 10 | println!("{:?}", data1); 11 | 12 | // Specify part of the fields and use the defaults for the rest 13 | let data2 = MyData { 14 | int_field: 42, 15 | ..Default::default() // Use the default for the rest 16 | }; 17 | println!("{:?}", data2); 18 | } 19 | -------------------------------------------------------------------------------- /3-Defining_Interfaces_with_Traits/6-Traits_in_the_Rust_Standard_Library_II/8-default_enum.rs: -------------------------------------------------------------------------------- 1 | #[allow(dead_code)] 2 | 3 | #[derive(Debug)] 4 | enum Pet { 5 | Cat, 6 | Dog, 7 | Bird, 8 | } 9 | 10 | impl Default for Pet { 11 | fn default() -> Pet { 12 | Pet::Cat 13 | } 14 | } 15 | 16 | fn main() { 17 | let default_pet: Pet = Default::default(); 18 | 19 | println!("{:?}", default_pet); 20 | } 21 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/2-Use_Declarative_Macros_to_Write_Less_Code/1-hello_world.rs: -------------------------------------------------------------------------------- 1 | macro_rules! hello { 2 | () => { // matches no argument 3 | // all call to "hello!()" will be expanded to this 4 | println!("hello"); 5 | }; 6 | } 7 | 8 | fn main() { 9 | hello!(); 10 | } 11 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/2-Use_Declarative_Macros_to_Write_Less_Code/2-vec.rs: -------------------------------------------------------------------------------- 1 | let x: Vec = vec![1, 2, 3]; 2 | // ^--- macro 3 | 4 | 5 | // expands to 6 | let x: Vec = { 7 | let mut temp_vec = Vec::new(); 8 | temp_vec.push(1); 9 | temp_vec.push(2); 10 | temp_vec.push(3); 11 | temp_vec 12 | }; 13 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/2-Use_Declarative_Macros_to_Write_Less_Code/3-vec_macro.rs: -------------------------------------------------------------------------------- 1 | macro_rules! vec { 2 | ( $( $x:expr ),* ) => { 3 | { // block 4 | let mut temp_vec = Vec::new(); 5 | $( 6 | temp_vec.push($x); 7 | )* 8 | temp_vec 9 | } 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/2-Use_Declarative_Macros_to_Write_Less_Code/4-macro_use.rs: -------------------------------------------------------------------------------- 1 | // Loads all macros from the "my_module_with_macros" module 2 | #[macro_use] 3 | mod my_module_with_macros; 4 | 5 | // Loads only my_macro! from my_crate_with_macros 6 | #[macro_use(my_macro)] 7 | extern crate my_crate_with_macros; 8 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_macro/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello_macro" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_macro/hello_macro_derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello_macro_derive" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [lib] 7 | proc-macro = true 8 | 9 | [dependencies] 10 | syn = "0.11.11" 11 | quote = "0.3.15" 12 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_macro/hello_macro_derive/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate proc_macro; 2 | extern crate syn; 3 | #[macro_use] 4 | extern crate quote; 5 | 6 | use proc_macro::TokenStream; 7 | 8 | #[proc_macro_derive(HelloMacro)] 9 | pub fn hello_macro_derive(input: TokenStream) -> TokenStream { 10 | // Construct a string representation of the type definition 11 | let s = input.to_string(); 12 | 13 | // Parse the string representation into DeriveInput 14 | let ast = syn::parse_derive_input(&s).unwrap(); 15 | 16 | // Build the impl 17 | let gen = impl_hello_macro(&ast); 18 | 19 | // Turn the impl_hello_macro output into TokenStream 20 | gen.parse().unwrap() 21 | } 22 | 23 | fn impl_hello_macro(ast: &syn::DeriveInput) -> quote::Tokens { 24 | let name = &ast.ident; // the "identifier", i.e. the "Cat" struct name 25 | quote! { // turn the code into quote::Tokens 26 | impl HelloMacro for #name { // template variable #name 27 | fn hello_macro() { 28 | println!("Hello, Macro! I'm a {}", stringify!(#name)); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_macro/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait HelloMacro { 2 | fn hello_macro(); 3 | } 4 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_world/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "hello_macro" 3 | version = "0.1.0" 4 | 5 | [[package]] 6 | name = "hello_macro_derive" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 11 | ] 12 | 13 | [[package]] 14 | name = "hello_world" 15 | version = "0.1.0" 16 | dependencies = [ 17 | "hello_macro 0.1.0", 18 | "hello_macro_derive 0.1.0", 19 | ] 20 | 21 | [[package]] 22 | name = "quote" 23 | version = "0.3.15" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | 26 | [[package]] 27 | name = "syn" 28 | version = "0.11.11" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | dependencies = [ 31 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 32 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 33 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 34 | ] 35 | 36 | [[package]] 37 | name = "synom" 38 | version = "0.11.3" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | dependencies = [ 41 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 42 | ] 43 | 44 | [[package]] 45 | name = "unicode-xid" 46 | version = "0.0.4" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | 49 | [metadata] 50 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 51 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 52 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 53 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 54 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_world/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello_world" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | hello_macro = { path = "../hello_macro" } 8 | hello_macro_derive = { path = "../hello_macro/hello_macro_derive" } 9 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/3-Using_Procedural_Macros_for_Custom_Derive/hello_world/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate hello_macro; // define the HelloMacro trait 2 | #[macro_use] 3 | extern crate hello_macro_derive; // define the derive 4 | 5 | use hello_macro::HelloMacro; 6 | 7 | #[derive(HelloMacro)] 8 | struct Cat; 9 | 10 | /* The #[derive(HelloMacro)] will implement this: 11 | impl HelloMacro for Cat { 12 | fn hello_macro() { 13 | println!("Hello, Macro! I'm a Cat!"); 14 | } 15 | } 16 | */ 17 | 18 | fn main() { 19 | Cat::hello_macro(); 20 | } 21 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/1-vec.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut vec = vec![1, 2, 3]; 3 | vec.push(4); 4 | assert_eq!(vec, [1, 2, 3, 4]); 5 | 6 | let vec = vec![0; 5]; 7 | // ^ ';' not ',' 8 | assert_eq!(vec, [0, 0, 0, 0, 0]); 9 | } 10 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/2-env.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let path: &'static str = env!("PATH"); // evaluated at compile time 3 | println!("the $PATH variable at the time of compiling was: {}", path); 4 | 5 | // env! will cause compilation error is not defined. 6 | let key: Option<&'static str> = option_env!("SECRET_KEY"); 7 | println!("the secret key might be: {:?}", key); 8 | } 9 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/3-formatting.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | print!("Print to stdout without newline"); 3 | println!("Print to stdout with newline"); 4 | eprint!("Print to stderr without newline"); 5 | eprintln!("Print to stderr with newline"); 6 | 7 | println!("My parameter is {}", "foo"); 8 | // My parameter is foo 9 | println!("{0} {1} {1} {0}", "foo", "bar"); 10 | // foo bar bar foo 11 | println!("{title}: {author} ({year})", 12 | title="Anna Karenina", 13 | author="Leo Tolstoy", 14 | year="1877"); 15 | // Anna Karenina: Leo Tolstoy (1877) 16 | 17 | let s_format: String = format!("Print to a Stirng with parameter: {}", "foo"); 18 | println!("{}", s_format); 19 | let s_concat: &str = concat!("one", "very", "long", "string"); 20 | println!("{}", s_concat); // oneverylongstring 21 | } 22 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/4-introspection.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let current_file = file!(); 3 | let current_line = line!(); 4 | let current_column = column!(); 5 | println!("{}, line {}, column {}", 6 | current_file, 7 | current_line, 8 | current_column, 9 | ); 10 | 11 | println!("{}", module_path!()); 12 | } 13 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/5-include.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let file_output = include!("external_rust_code.txt"); 3 | println!("{}", file_output); 4 | 5 | let file_string = include_str!("external_string.txt"); 6 | println!("{}", file_string); 7 | 8 | // let byte_array: &'static [u8; N] = include_bytes!("external_string.txt"); 9 | } 10 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/external_rust_code.txt: -------------------------------------------------------------------------------- 1 | ["one", "very", "long", "string"].join("") 2 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/4-Macros_in_the_Rust_Standard_Library_I/external_string.txt: -------------------------------------------------------------------------------- 1 | oneverylongstring 2 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/5-Macros_in_the_Rust_Standard_Library_II/1-cfg.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | if cfg!(target_os = "macos") { 3 | println!("Run the MacOS-specific code"); 4 | } 5 | else if cfg!(target_os = "linux"){ 6 | println!("Run the Linux-specific code"); 7 | LinuxCode {}; 8 | } 9 | else { 10 | println!("We don't support this architecture"); 11 | } 12 | } 13 | 14 | #[cfg(target_os = "linux")] 15 | struct LinuxCode; 16 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/5-Macros_in_the_Rust_Standard_Library_II/2-try.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::fs::File; 3 | use std::io::prelude::*; 4 | 5 | fn write_to_file_try() -> Result<(), io::Error> { 6 | // File::create() -> Result 7 | let mut f = try!(File::create("myfile.txt")); 8 | f.write_all(b"Hello world"); 9 | Ok(()) 10 | } 11 | 12 | // equivalent to 13 | fn write_to_file_match() -> Result<(), io::Error> { 14 | match File::create("myfile.txt") { 15 | Ok(mut f) => f.write_all(b"Hello world"), 16 | Err(e) => return Err(e) // early return an Err 17 | } 18 | } 19 | 20 | // try! can be shortened to '?' 21 | fn write_to_file_shorthand() -> Result<(), io::Error> { 22 | File::create("myfile.txt")?.write_all(b"Hello world") 23 | // ^- shorthand for try! 24 | } 25 | 26 | fn main() { 27 | write_to_file_match().unwrap(); 28 | write_to_file_try().unwrap(); 29 | write_to_file_shorthand().unwrap(); 30 | } 31 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/5-Macros_in_the_Rust_Standard_Library_II/3-panic.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | panic!("I need to crash!"); 3 | // thread 'main' panicked at 'I need to crash!' 4 | } 5 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/5-Macros_in_the_Rust_Standard_Library_II/4-unimplemented.rs: -------------------------------------------------------------------------------- 1 | trait Animal { 2 | fn walk(&self); 3 | fn make_noise(&self); 4 | } 5 | 6 | struct Cat; 7 | 8 | impl Animal for Cat { 9 | fn walk(&self) { 10 | unimplemented!(); 11 | } 12 | fn make_noise(&self) { 13 | unimplemented!(); 14 | } 15 | } 16 | 17 | fn main() { 18 | let cat = Cat {}; 19 | cat.walk(); // thread 'main' panicked at 'not yet implemented' 20 | } 21 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/5-Macros_in_the_Rust_Standard_Library_II/5-unreachable.rs: -------------------------------------------------------------------------------- 1 | fn check_number(x: i32) { 2 | match x { 3 | n if n > 0 => println!("positive"), 4 | n if n == 0 => println!("zero"), 5 | n if n < 0 => println!("negative"), 6 | _ => unreachable!(), 7 | // thread 'main' panicked at 'internal error: entered unreachable code' 8 | } 9 | } 10 | fn main() { 11 | check_number(42); 12 | } 13 | -------------------------------------------------------------------------------- /4-Hacking_the_Language_with_Marcos/5-Macros_in_the_Rust_Standard_Library_II/6-assertions.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | assert!(1 == 1); 3 | 4 | let x = true; 5 | assert!(x, "x isn't true!"); 6 | 7 | assert_eq!(1, 1); 8 | 9 | let y = 10; 10 | let z = 20; 11 | assert_eq!(y, z) 12 | 13 | 14 | // Only run in un-optimized builds 15 | debug_assert!(1 == 1); 16 | debug_assert_eq!(1, 1); 17 | } 18 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/1-Introducing_Crates/create_crates.sh: -------------------------------------------------------------------------------- 1 | cargo new example-binary --bin 2 | cargo new example-library --lib 3 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/1-Introducing_Crates/example-binary/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-binary" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/1-Introducing_Crates/example-binary/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/1-Introducing_Crates/example-library/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-library" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/1-Introducing_Crates/example-library/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | assert_eq!(2 + 2, 4); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/1-simple_module.rs: -------------------------------------------------------------------------------- 1 | mod cat { 2 | fn meow() { // Should be "pub fn", we'll talk about this later 3 | } 4 | } 5 | 6 | fn main() { 7 | cat::meow(); 8 | } 9 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/2-nested_modules.rs: -------------------------------------------------------------------------------- 1 | mod animal { 2 | fn move_around() {} 3 | 4 | mod cat { 5 | fn meow() {} 6 | } 7 | 8 | mod dog { 9 | fn bark(){} 10 | } 11 | } 12 | 13 | /* 14 | animal::move_around() 15 | 16 | animal::cat::meow() 17 | 18 | animal::dog::bark() 19 | */ 20 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/3-folder-structure/animal/cat.rs: -------------------------------------------------------------------------------- 1 | fn meow() {} 2 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/3-folder-structure/animal/dog.rs: -------------------------------------------------------------------------------- 1 | fn bark() {} 2 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/3-folder-structure/animal/mod.rs: -------------------------------------------------------------------------------- 1 | fn move_around() {} 2 | 3 | mod cat; 4 | mod dog; 5 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/3-folder-structure/lib.rs: -------------------------------------------------------------------------------- 1 | mod animal; // the content moved to animal/mod.rs 2 | 3 | fn main() { 4 | animal::cat::meow() 5 | } 6 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/2-Using_Modules_to_Define_the_Structure_of_Crates/4-pub.rs: -------------------------------------------------------------------------------- 1 | mod animal { 2 | pub fn move_around() {} 3 | 4 | pub mod cat { 5 | pub fn meow() {} 6 | } 7 | 8 | mod dog { 9 | fn bark() {} 10 | } 11 | } 12 | 13 | fn main() { 14 | animal::move_around(); 15 | animal::cat::meow(); 16 | animal::dog::bark(); // error[E0603]: module `dog` is private 17 | } 18 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/animal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "animal" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/animal/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod mammal { 2 | pub mod cat { 3 | pub fn meow() { 4 | println!("Meow! Meow!"); 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/crates_io_example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "crates_io_example" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | rand = "0.5.5" 8 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/crates_io_example/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; // compile and link the rand crate 2 | 3 | fn main() { 4 | let x: u8 = rand::random(); 5 | println!("{}", x); 6 | } 7 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/github_example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "github_example" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | rand = { git = "https://github.com/rust-random/rand.git" } 8 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/github_example/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; // compile and link the rand crate 2 | 3 | fn main() { 4 | let x: u8 = rand::random(); 5 | println!("{}", x); 6 | } 7 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/local_example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "local_example" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | animal = { path = "../animal" } 8 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/3-Using_a_Crate_With_Cargo_toml/local_example/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate animal; 2 | 3 | use animal::mammal::cat::*; 4 | 5 | fn main() { 6 | meow(); 7 | } 8 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/4-Publishing_to_crates_io/publish-example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "publish-example" 3 | version = "0.1.0" 4 | authors = ["Shing Lyu "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /5-Reusing_the_Code_With_Other_People_Using_Modules_and_Crates/4-Publishing_to_crates_io/publish-example/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | assert_eq!(2 + 2, 4); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Building Reusable Code with Rust [Video] 5 | This is the code repository for [Building Reusable Code with Rust [Video]](https://www.packtpub.com/application-development/building-reusable-code-rust-video?utm_source=github&utm_medium=repository&utm_campaign=9781788399524), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the video course from start to finish. 6 | ## About the Video Course 7 | Rust is the ideal language for writing safe, correct code in a way that won't make you pull your hair out. This course will teach you how to build reusable Rust code so that you can stop copy-pasting code. Write one code that can adapt to many different usages. 8 | You will reuse code by using advanced features like Traits, Generics and Macros. You will work with different forms of code reuse, loops, map, filter and fold to save time and resources. Achieve higher level reuse without sacrificing run-time performance. Organize your code into modules and crates to publish them to crates.io. 9 | By the end of the course you will be able to avoid code duplication to write clean reusable code 10 | Rust is the ideal language for writing safe, correct code in a way that won't make you pull your hair out. This course will teach you how to build reusable Rust code so that you can stop copy-pasting code. Write one code that can adapt to many different usages. 11 | You will reuse code by using advanced features like Traits, Generics and Macros. You will work with different forms of code reuse, loops, map, filter and fold to save time and resources. Achieve higher level reuse without sacrificing run-time performance. Organize your code into modules and crates to publish them to crates.io. 12 | By the end of the course you will be able to avoid code duplication to write clean reusable code 13 | 14 | 15 |

What You Will Learn

16 |
17 |
    18 |
  • Write clean and reusable Rust code for your applications 19 |
  • Use loop, map, filter and fold to avoid duplicated code 20 |
  • Understand generics and learn to use it to abstract algorithms for multiple data types 21 |
  • Define and enforce clear interface using traits 22 |
  • Work with macros and compiler plugins for metaprogramming 23 |
  • Explore how the standard library uses features such as generics, traits and macros 24 |
  • Structure your code with modules and crates and publish them online
25 | 26 | ## Instructions and Navigation 27 | ### Assumed Knowledge 28 | To fully benefit from the coverage included in this course, you will need:
29 | This course will appeal to Rust developers who are already familiar with the language and want to learn how to build Rust libraries that are maintainable, reusable and has an API that honors Rust convention 30 | ### Technical Requirements 31 | This course has the following software requirements:
32 | This course has the following software requirements: 33 | 34 | ● Operating system: OSX 10.7+, Window 7+, Linux 2.6.18+ 35 | 36 | ● Browser: All modern browsers 37 | 38 | ● Rust compiler 39 | This course has been tested on the following system configuration: 40 | 41 | ● OS: Linux 4.15.0 (Ubuntu 16.04.2 LTS) 42 | 43 | ● Processor: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 44 | 45 | ● Memory: 8GB 46 | 47 | ● Hard Disk Space: 100GB 48 | 49 | ● Video Card: Intel HD Graphic 620 50 | 51 | 52 | ## Related Products 53 | * [Learning Rust [Video]](https://www.packtpub.com/application-development/learning-rust-video?utm_source=github&utm_medium=repository&utm_campaign=9781788477918) 54 | 55 | * [RUST: The Easy Way [Video]](https://www.packtpub.com/application-development/rustthe-easy-way-video?utm_source=github&utm_medium=repository&utm_campaign=9781788396240) 56 | 57 | * [Introduction to Rust Programming [Video]](https://www.packtpub.com/application-development/introduction-rust-programming-video?utm_source=github&utm_medium=repository&utm_campaign=9781786466068) 58 | 59 | --------------------------------------------------------------------------------