├── Chapter04 ├── foo.txt ├── .gitignore ├── creating_generic_vec.rs ├── complex │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── super_player │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ ├── media.rs │ │ └── main.rs ├── unusable_str.rs ├── generic_enum.rs ├── trait_bound_basics.rs ├── using_generic_func.rs ├── trait_bound_basics_fixed.rs ├── generic_function.rs ├── impl_trait_syntax.rs ├── let_pattern_wrapper.rs ├── impl_trait_closure.rs ├── trait_bounds_types.rs ├── generic_struct_impl.rs ├── impl_trait_both.rs ├── trait_bound_intro.rs ├── using_generic_vec.rs ├── generic_struct.rs ├── trait_bound_functions.rs ├── trait_bound_intro_fixed.rs ├── trait_objects.rs ├── trait_composition.rs ├── trait_inheritance.rs └── expressions.rs ├── Chapter07 ├── string_owned.rs ├── re-exports │ ├── src │ │ ├── foo.rs │ │ ├── foo │ │ │ └── bar.rs │ │ └── main.rs │ ├── Cargo.lock │ └── Cargo.toml ├── str_type.rs ├── unusable_str.rs ├── string_concat.rs ├── string_indexing.rs ├── object_safety.rs ├── scopes.rs ├── string_chars.rs ├── strings.rs ├── safe_arithmetic.rs ├── fn_once.rs ├── string_range_slice.rs ├── const_fn.rs ├── refutable_pattern.rs ├── function_types.rs ├── type_inference_iterator.rs ├── fn_closure.rs ├── fn_mut_closure.rs ├── loop_expr.rs ├── serde_demo │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── borrowed_strings.rs ├── const_fn_file.rs ├── nested_imports.rs ├── match_ref.rs ├── destructure_enum.rs ├── string_slices_func.rs ├── ufcs.rs ├── type_alias.rs ├── unions.rs ├── if_expr.rs ├── block_expr.rs ├── trait_constants.rs ├── destructure_struct.rs ├── destructure_func_param.rs ├── let_ref_mut.rs ├── enum_struct_consts.rs ├── pointer_layouts.rs ├── string_apis.rs └── custom_iterator.rs ├── Chapter11 ├── slog_demo │ ├── README.md │ ├── Cargo.toml │ └── src │ │ ├── weapon.rs │ │ ├── enemy.rs │ │ ├── player.rs │ │ └── main.rs ├── log4rs_demo │ ├── my_app │ │ ├── log │ │ │ └── requests.log │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── my_lib │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── Cargo.toml │ ├── log │ │ └── my_lib.log │ └── config │ │ └── log4rs.yaml ├── user_auth │ ├── Cargo.toml │ ├── src │ │ └── lib.rs │ └── Cargo.lock └── env_logger_demo │ ├── Cargo.toml │ └── src │ └── main.rs ├── Chapter05 ├── data.txt ├── todolist_parser │ ├── Cargo.lock │ ├── examples │ │ ├── todo │ │ ├── todo_junk │ │ └── basics.rs │ ├── Cargo.toml │ └── src │ │ ├── error.rs │ │ └── lib.rs ├── static_lifetime.rs ├── multiple_lifetimes.rs ├── mutable_borrow.rs ├── ownership_primitives.rs ├── lifetime_basics.rs ├── lifetime_struct.rs ├── uninitialized_reads.c ├── using_lifetimes.rs ├── buffer_overflow.c ├── exclusive_borrow.rs ├── recursive_type.rs ├── main_result.rs ├── return_func_ref.rs ├── stack_basics.rs ├── explicit_lifetimes.rs ├── catch_unwind.rs ├── making_copy_types.rs ├── borrowing_basics.rs ├── making_copy_types_fixed.rs ├── ownership_basics.rs ├── ownership_closures.rs ├── explicit_copy.rs ├── using_options.rs ├── using_options_unwrap.rs ├── result_basics.rs ├── box_basics.rs ├── ownership_functions.rs ├── ownership_methods.rs ├── cell.rs ├── lifetime_bounds.rs ├── lifetime_subtyping.rs ├── using_options_match.rs ├── drop.rs ├── without_cell.rs ├── lifetime_bounds_short.rs ├── iterator_invalidation.cpp ├── ownership_functions_back.rs ├── borrowing_functions.rs ├── using_question_operator.rs ├── ownership_match.rs ├── borrowing_match.rs ├── panic_unwinding.rs ├── result_basics_fixed.rs ├── refcell_basics.rs ├── lifetime_impls.rs ├── using_map.rs ├── scopes.rs ├── result_common_pattern.rs ├── cell_cache.rs ├── linked_list.rs ├── rc_weak.rs └── rc_3.rs ├── Chapter06 ├── data.txt ├── todolist_parser │ ├── Cargo.lock │ ├── examples │ │ ├── todo │ │ ├── malformed_todo │ │ ├── README.md │ │ └── basics.rs │ ├── Cargo.toml │ └── src │ │ ├── error.rs │ │ └── lib.rs ├── create_result.rs ├── main_result.rs ├── catch_unwind.rs ├── using_options.rs ├── create_result_fixed.rs ├── using_options_unwrap.rs ├── result_basics.rs ├── using_options_match.rs ├── using_question_operator.rs ├── panic_unwinding.rs ├── result_basics_fixed.rs ├── using_map.rs └── result_common_pattern.rs ├── Chapter12 ├── rudis_sync │ ├── .gitignore │ ├── Cargo.toml │ ├── Cargo.lock │ └── src │ │ ├── main.rs │ │ └── commands.rs └── rudis_async │ ├── Cargo.toml │ └── src │ ├── codec.rs │ ├── main.rs │ └── commands.rs ├── Chapter03 ├── logic_gates │ ├── .gitignore │ ├── logic_gate.png │ ├── Cargo.toml │ ├── README.md │ ├── .travis.yml │ ├── tests │ │ └── half_adder.rs │ ├── LICENSE │ └── src │ │ └── lib.rs ├── first_unit_test.rs ├── unit_test │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── doctest_demo │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── bench_example │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── integration_test │ ├── Cargo.lock │ ├── src │ │ └── lib.rs │ ├── Cargo.toml │ └── tests │ │ ├── common.rs │ │ └── sum.rs ├── logic_gates_icon.png ├── panic_test.rs ├── silly_loop.rs ├── criterion_demo │ ├── Cargo.toml │ ├── benches │ │ └── fibonacci.rs │ └── src │ │ └── lib.rs └── ignored_test.rs ├── Chapter02 ├── myexponent │ ├── Cargo.lock │ ├── examples │ │ └── basic.rs │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── workspace_demo │ ├── app │ │ ├── src │ │ │ └── main.rs │ │ └── Cargo.toml │ ├── my_crate │ │ ├── src │ │ │ └── lib.rs │ │ └── Cargo.toml │ ├── Cargo.toml │ └── Cargo.lock ├── my_program │ ├── foo.rs │ ├── foo │ │ └── bar.rs │ └── main.rs ├── file_as_module.rs ├── imgtool │ ├── assets │ │ └── ferris.png │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── modules_demo │ ├── main.rs │ └── foo.rs ├── mod_within.rs └── cargo_manifest_example │ └── Cargo.toml ├── Chapter09 ├── macro_map │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── into_map_demo │ ├── into_map │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── Cargo.toml │ ├── into_map_derive │ │ ├── Cargo.toml │ │ ├── src │ │ │ └── lib.rs │ │ └── Cargo.lock │ ├── src │ │ └── main.rs │ └── Cargo.lock ├── http_tester │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── c_macros_rust.rs ├── c_macros.c ├── print_formatting.rs └── first_macro.rs ├── Chapter10 ├── rust_from_c │ ├── Cargo.lock │ ├── Makefile │ ├── main │ ├── Cargo.toml │ ├── main.c │ └── src │ │ └── lib.rs ├── native_counter │ ├── README.md │ ├── .gitignore │ ├── lib │ │ └── index.js │ ├── main.js │ ├── native │ │ ├── build.rs │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── package.json ├── word_suffix │ ├── main.py │ ├── Cargo.toml │ ├── README.md │ └── src │ │ └── lib.rs ├── edit_distance │ ├── liblevenshtein.a │ ├── examples │ │ └── basic.rs │ ├── src │ │ ├── bindings.rs │ │ └── lib.rs │ ├── Cargo.toml │ └── build.rs ├── c_from_rust │ ├── mystrlen.c │ ├── build.rs │ ├── Cargo.toml │ ├── Cargo.lock │ └── src │ │ └── main.rs ├── unsafe_function.rs ├── both_true_false.c └── unsafe_trait_and_impl.rs ├── Chapter01 ├── unit_struct.rs ├── use.rs ├── while.rs ├── if_else.rs ├── functions.rs ├── greet.rs ├── loops.rs ├── if_assign.rs ├── if_else_no_value.rs ├── arrays.rs ├── function_mut.rs ├── tuples.rs ├── variables.rs ├── first_program.rs ├── strings.rs ├── for_loops.rs ├── closures.rs ├── match_expression.rs ├── slices.rs ├── vec.rs ├── hashmaps.rs ├── tuple_struct.rs ├── structs.rs ├── loop_labels.rs ├── struct_methods.rs ├── enums.rs ├── enum_methods.rs └── exercise_word_counter.rs ├── charts ├── Heap Sort.png ├── runtime.n.png ├── Bubble Sort.png ├── Merge Sort.png ├── Quick Sort.png ├── Shell Sort.png ├── Stdlib Sort.png ├── runtime.exp.png ├── runtime.logn.png ├── runtime.n2.png ├── runtime.nlogn.png ├── runtime.complexity.png ├── bench.seq.std.vs.naive.png ├── bench.maps.std.vs.naive.png └── bench.trees.std.vs.naive.png ├── Chapter14 ├── Cargo.toml └── src │ ├── singly_linked_list.rs │ └── dynamic_array.rs ├── Chapter15 ├── Cargo.toml └── src │ ├── heap.rs │ ├── binary_search_tree.rs │ └── trie.rs ├── Chapter16 ├── Cargo.toml └── src │ └── map.rs ├── Chapter19 └── Cargo.toml ├── Chapter20 └── Cargo.toml ├── Chapter21 ├── Cargo.toml └── src │ ├── prng.rs │ └── knapsack.rs ├── Chapter13 ├── linksnap │ ├── test_server.sh │ ├── Cargo.toml │ └── src │ │ ├── main.rs │ │ ├── links.rs │ │ ├── route_handlers.rs │ │ └── state.rs ├── shorten │ ├── Cargo.toml │ └── src │ │ └── main.rs └── hyperurl │ ├── Cargo.toml │ └── src │ ├── shortener.rs │ ├── main.rs │ ├── index.rs │ └── service.rs ├── Chapter08 ├── actor_demo │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── thread_basics.rs ├── thread_read.rs ├── threads_shared_owner.rs ├── thread_moves.rs ├── thread_mut.rs ├── thread_basics_join.rs ├── mutex_basics.rs ├── thread_rwlock.rs ├── customize_threads.rs ├── thread_rc.rs ├── async_channels.rs ├── thread_arc.rs ├── arc_mutex.rs ├── threads_sharing.rs └── sync_channels.rs ├── LICENSE └── README.md /Chapter04/foo.txt: -------------------------------------------------------------------------------- 1 | Rust -------------------------------------------------------------------------------- /Chapter07/string_owned.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter04/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /Chapter11/slog_demo/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_app/log/requests.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/data.txt: -------------------------------------------------------------------------------- 1 | If you got no Option, use Result ! -------------------------------------------------------------------------------- /Chapter06/data.txt: -------------------------------------------------------------------------------- 1 | If you got no Option, use Result ! -------------------------------------------------------------------------------- /Chapter12/rudis_sync/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_app/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /Chapter07/re-exports/src/foo.rs: -------------------------------------------------------------------------------- 1 | pub mod bar; 2 | 3 | pub use bar::Bar; -------------------------------------------------------------------------------- /Chapter03/logic_gates/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /Chapter04/creating_generic_vec.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = Vec::new(); 3 | } -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_lib/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /Chapter07/re-exports/src/foo/bar.rs: -------------------------------------------------------------------------------- 1 | // re-exports/src/foo/bar.rs 2 | 3 | pub struct Bar; -------------------------------------------------------------------------------- /Chapter04/complex/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "complex" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter02/myexponent/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "myexponent" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter02/workspace_demo/app/src/main.rs: -------------------------------------------------------------------------------- 1 | 2 | fn main() { 3 | my_crate::greet(); 4 | } 5 | -------------------------------------------------------------------------------- /Chapter03/first_unit_test.rs: -------------------------------------------------------------------------------- 1 | 2 | #[test] 3 | fn basic_test() { 4 | assert!(true); 5 | } 6 | -------------------------------------------------------------------------------- /Chapter03/unit_test/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "unit_test" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter07/re-exports/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "re-exports" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter09/macro_map/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "macro_map" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter03/doctest_demo/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "doctest_demo" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter04/super_player/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "super_player" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter10/rust_from_c/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "rust_from_c" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter03/bench_example/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "bench_example" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter05/todolist_parser/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "todolist_parser" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter05/todolist_parser/examples/todo: -------------------------------------------------------------------------------- 1 | Read AOCP 2 | Get dog for walk 3 | Get to gym 4 | Eat 5 | Sleep 6 | -------------------------------------------------------------------------------- /Chapter06/todolist_parser/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "todolist_parser" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter06/todolist_parser/examples/todo: -------------------------------------------------------------------------------- 1 | Read AOCP 2 | Get dog for walk 3 | Get to gym 4 | Eat 5 | Sleep 6 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/into_map/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "into_map" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter03/integration_test/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "integration_test" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /Chapter07/str_type.rs: -------------------------------------------------------------------------------- 1 | // str_type.rs 2 | 3 | fn main() { 4 | let message: str = "Wait, but why ?"; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "my_lib", 5 | "my_app" 6 | ] 7 | -------------------------------------------------------------------------------- /Chapter02/workspace_demo/my_crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | pub fn greet() { 3 | println!("Hi from my crate"); 4 | } 5 | -------------------------------------------------------------------------------- /Chapter04/unusable_str.rs: -------------------------------------------------------------------------------- 1 | // unusable_str.rs 2 | 3 | fn main() { 4 | let message: str = "Wait, but why ?"; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter07/unusable_str.rs: -------------------------------------------------------------------------------- 1 | // unusable_str.rs 2 | 3 | fn main() { 4 | let message: str = "Wait, but why ?"; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter10/rust_from_c/Makefile: -------------------------------------------------------------------------------- 1 | 2 | main: 3 | cargo build 4 | gcc main.c -L ./target/debug -lstringutils -o main 5 | -------------------------------------------------------------------------------- /Chapter03/integration_test/src/lib.rs: -------------------------------------------------------------------------------- 1 | // function we want to test 2 | pub fn sum(a: i8, b: i8) -> i8 { 3 | a + b 4 | } 5 | -------------------------------------------------------------------------------- /Chapter10/native_counter/README.md: -------------------------------------------------------------------------------- 1 | # native_counter 2 | 3 | A native nodejs module in Rust to count words in a given text 4 | -------------------------------------------------------------------------------- /Chapter01/unit_struct.rs: -------------------------------------------------------------------------------- 1 | // unit_struct.rs 2 | 3 | struct DummyStruct; 4 | 5 | fn main() { 6 | let a = DummyStruct; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter05/static_lifetime.rs: -------------------------------------------------------------------------------- 1 | // static_lifetime.rs 2 | 3 | fn main() { 4 | let _a: &'static str = "I live forever"; 5 | } 6 | -------------------------------------------------------------------------------- /Chapter10/word_suffix/main.py: -------------------------------------------------------------------------------- 1 | import word_suffix 2 | 3 | print(word_suffix.find_words("Baz, Jazz, Mash, Splash, Squash", "sh")) 4 | -------------------------------------------------------------------------------- /charts/Heap Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/Heap Sort.png -------------------------------------------------------------------------------- /charts/runtime.n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/runtime.n.png -------------------------------------------------------------------------------- /charts/Bubble Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/Bubble Sort.png -------------------------------------------------------------------------------- /charts/Merge Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/Merge Sort.png -------------------------------------------------------------------------------- /charts/Quick Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/Quick Sort.png -------------------------------------------------------------------------------- /charts/Shell Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/Shell Sort.png -------------------------------------------------------------------------------- /charts/Stdlib Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/Stdlib Sort.png -------------------------------------------------------------------------------- /charts/runtime.exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/runtime.exp.png -------------------------------------------------------------------------------- /charts/runtime.logn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/runtime.logn.png -------------------------------------------------------------------------------- /charts/runtime.n2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/runtime.n2.png -------------------------------------------------------------------------------- /Chapter02/my_program/foo.rs: -------------------------------------------------------------------------------- 1 | 2 | mod bar; 3 | 4 | pub use self::bar::Bar; 5 | 6 | pub fn do_foo() { 7 | println!("Hi from foo!"); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/myexponent/examples/basic.rs: -------------------------------------------------------------------------------- 1 | 2 | use myexponent::pow; 3 | 4 | fn main() { 5 | println!("8 raised to 2 is {}", pow(8, 2)); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter02/workspace_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | # workspace_demo/Cargo.toml 2 | 3 | [workspace] 4 | members = [ 5 | "app", 6 | "my_crate" 7 | ] 8 | -------------------------------------------------------------------------------- /Chapter06/create_result.rs: -------------------------------------------------------------------------------- 1 | // create_result.rs 2 | 3 | fn main() { 4 | let my_result = Ok(64); 5 | let my_err = Err("oh no!"); 6 | } 7 | -------------------------------------------------------------------------------- /Chapter07/string_concat.rs: -------------------------------------------------------------------------------- 1 | // string_concat.rs 2 | 3 | fn main() { 4 | let a = "Foo"; 5 | let b = "Bar"; 6 | let c = a + b; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/native_counter/.gitignore: -------------------------------------------------------------------------------- 1 | native/target 2 | native/index.node 3 | native/artifacts.json 4 | **/*~ 5 | **/node_modules 6 | **/.DS_Store 7 | -------------------------------------------------------------------------------- /charts/runtime.nlogn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/runtime.nlogn.png -------------------------------------------------------------------------------- /Chapter02/file_as_module.rs: -------------------------------------------------------------------------------- 1 | // file_as_module.rs 2 | 3 | mod foo; 4 | use crate::foo::Bar; 5 | 6 | fn main() { 7 | let eatable = Cake; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/rust_from_c/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter10/rust_from_c/main -------------------------------------------------------------------------------- /Chapter03/logic_gates_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter03/logic_gates_icon.png -------------------------------------------------------------------------------- /Chapter05/todolist_parser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "todolist_parser" 3 | version = "0.1.0" 4 | authors = ["creativcoder"] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /Chapter07/re-exports/src/main.rs: -------------------------------------------------------------------------------- 1 | // re-exports_demo/src/main.rs 2 | 3 | mod foo; 4 | 5 | use foo::Bar; 6 | 7 | fn main() { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /charts/runtime.complexity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/runtime.complexity.png -------------------------------------------------------------------------------- /Chapter01/use.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::char::from_u32; 3 | 4 | fn main() { 5 | let heart = from_u32(0x2764).unwrap(); 6 | println!("I {} Rust!", heart); 7 | } -------------------------------------------------------------------------------- /Chapter02/my_program/foo/bar.rs: -------------------------------------------------------------------------------- 1 | 2 | pub struct Bar; 3 | 4 | impl Bar { 5 | pub fn hello() { 6 | println!("Hello from Bar !"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/string_indexing.rs: -------------------------------------------------------------------------------- 1 | // strings_indexing.rs 2 | 3 | fn main() { 4 | let hello = String::from("Hello"); 5 | let first_char = hello[0]; 6 | } 7 | -------------------------------------------------------------------------------- /charts/bench.seq.std.vs.naive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/bench.seq.std.vs.naive.png -------------------------------------------------------------------------------- /Chapter02/imgtool/assets/ferris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter02/imgtool/assets/ferris.png -------------------------------------------------------------------------------- /charts/bench.maps.std.vs.naive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/bench.maps.std.vs.naive.png -------------------------------------------------------------------------------- /charts/bench.trees.std.vs.naive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/charts/bench.trees.std.vs.naive.png -------------------------------------------------------------------------------- /Chapter01/while.rs: -------------------------------------------------------------------------------- 1 | 2 | fn main() { 3 | let mut x = 1000; 4 | while x > 0 { 5 | println!("{} more runs to go", x); 6 | x -= 1; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/logic_gates/logic_gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter03/logic_gates/logic_gate.png -------------------------------------------------------------------------------- /Chapter04/super_player/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "super_player" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /Chapter05/multiple_lifetimes.rs: -------------------------------------------------------------------------------- 1 | // multiple_lifetimes.rs 2 | 3 | struct Decoder<'a, 'b, S, R> { 4 | schema: &'a S, 5 | reader: &'b R 6 | } 7 | 8 | fn main() {} 9 | -------------------------------------------------------------------------------- /Chapter09/macro_map/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "macro_map" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /Chapter10/native_counter/lib/index.js: -------------------------------------------------------------------------------- 1 | // native_counter/lib/index.js 2 | 3 | var word_counter = require('../native'); 4 | module.exports = word_counter.count_words; 5 | -------------------------------------------------------------------------------- /Chapter02/modules_demo/main.rs: -------------------------------------------------------------------------------- 1 | // modules_demo/main.rs 2 | 3 | mod foo; 4 | 5 | use crate::foo::Bar; 6 | 7 | fn main() { 8 | let _bar = Bar::init(); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter02/my_program/main.rs: -------------------------------------------------------------------------------- 1 | // my_program/main.rs 2 | 3 | mod foo; 4 | 5 | use foo::Bar; 6 | 7 | fn main() { 8 | foo::do_foo(); 9 | Bar::hello(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter04/generic_enum.rs: -------------------------------------------------------------------------------- 1 | // generic_enum.rs 2 | 3 | enum Transmission { 4 | Signal(T), 5 | NoSignal 6 | } 7 | 8 | fn main() { 9 | // stuff 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/mutable_borrow.rs: -------------------------------------------------------------------------------- 1 | // mutable_borrow.rs 2 | 3 | fn main() { 4 | let a = String::from("Owned string"); 5 | let a_ref = &mut a; 6 | a_ref.push('!'); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter05/ownership_primitives.rs: -------------------------------------------------------------------------------- 1 | // ownership_primitives.rs 2 | 3 | fn main() { 4 | let foo = 4623; 5 | let bar = foo; 6 | println!("{:?} {:?}", foo, bar); 7 | } -------------------------------------------------------------------------------- /Chapter10/edit_distance/liblevenshtein.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter10/edit_distance/liblevenshtein.a -------------------------------------------------------------------------------- /Chapter02/imgtool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "imgtool" 3 | version = "0.1.0" 4 | authors = ["creativcoder"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | image = "0.19.0" 9 | -------------------------------------------------------------------------------- /Chapter05/lifetime_basics.rs: -------------------------------------------------------------------------------- 1 | // lifetime_basics.rs 2 | 3 | struct SomeRef { 4 | part: &T 5 | } 6 | 7 | fn main() { 8 | let a = SomeRef { part: &43 }; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter11/user_auth/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "user_auth" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | log = "0.4.6" -------------------------------------------------------------------------------- /Chapter04/complex/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "complex" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter05/lifetime_struct.rs: -------------------------------------------------------------------------------- 1 | // lifetime_struct.rs 2 | 3 | struct Number<'a> { 4 | num: &'a u8 5 | } 6 | 7 | fn main() { 8 | let _n = Number {num: &545}; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter05/todolist_parser/examples/todo_junk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter05/todolist_parser/examples/todo_junk -------------------------------------------------------------------------------- /Chapter06/todolist_parser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "todolist_parser" 3 | version = "0.1.0" 4 | authors = ["creativcoders@gmail.com"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter07/object_safety.rs: -------------------------------------------------------------------------------- 1 | // object_safety.rs 2 | 3 | trait Foo { 4 | fn foo(); 5 | } 6 | 7 | fn generic(val: &Foo) { 8 | 9 | } 10 | 11 | fn main() { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my_lib" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | log = "0.4" -------------------------------------------------------------------------------- /Chapter02/myexponent/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "myexponent" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter03/unit_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "unit_test" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter04/super_player/src/media.rs: -------------------------------------------------------------------------------- 1 | // super_player/src/media.rs 2 | 3 | pub trait Playable { 4 | fn play(&self); 5 | fn pause() { 6 | println!("Paused"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/uninitialized_reads.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | int main() 4 | { 5 | int arr[5]; 6 | 7 | for (int i = 0; i < 5; i++) 8 | printf("%d ", arr[i]); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter05/using_lifetimes.rs: -------------------------------------------------------------------------------- 1 | // using_lifetimes.rs 2 | 3 | struct SomeRef<'a, T> { 4 | part: &'a T 5 | } 6 | 7 | fn main() { 8 | let _a = SomeRef { part: &43 }; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter07/re-exports/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "re-exports" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter07/scopes.rs: -------------------------------------------------------------------------------- 1 | // scopes.rs 2 | 3 | fn main() { 4 | let mut b = 4; 5 | { 6 | let mut a = 34 + b; 7 | a += 1; 8 | } 9 | 10 | b = a; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/string_chars.rs: -------------------------------------------------------------------------------- 1 | // strings_chars.rs 2 | 3 | fn main() { 4 | let hello = String::from("Hello"); 5 | for c in hello.chars() { 6 | println!("{}", c); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/strings.rs: -------------------------------------------------------------------------------- 1 | // strings.rs 2 | 3 | fn main() { 4 | let a: String = "Hello".to_string(); 5 | let b = String::from("Hello"); 6 | let c = "World".to_owned(); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/c_from_rust/mystrlen.c: -------------------------------------------------------------------------------- 1 | // count_string.c 2 | 3 | unsigned int mystrlen(char *str) { 4 | unsigned int c; 5 | for (c=0; *str != '\0'; c++, *str++); 6 | return c; 7 | } -------------------------------------------------------------------------------- /Chapter02/modules_demo/foo.rs: -------------------------------------------------------------------------------- 1 | // modules_demo/foo.rs 2 | 3 | pub struct Bar; 4 | 5 | impl Bar { 6 | pub fn init() { 7 | println!("Bar type initialized"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter03/doctest_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "doctest_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter03/logic_gates/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "logic_gates" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter06/todolist_parser/examples/malformed_todo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/HEAD/Chapter06/todolist_parser/examples/malformed_todo -------------------------------------------------------------------------------- /Chapter14/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = '2018' 3 | name = "ch4" 4 | version = "0.1.0" 5 | authors = ["Claus Matzinger "] 6 | 7 | [dependencies] 8 | rand = "^0.5" -------------------------------------------------------------------------------- /Chapter15/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = '2018' 3 | name = "ch5" 4 | version = "0.1.0" 5 | authors = ["Claus Matzinger "] 6 | 7 | [dependencies] 8 | rand = "^0.5" -------------------------------------------------------------------------------- /Chapter16/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = '2018' 3 | name = "ch6" 4 | version = "0.1.0" 5 | authors = ["Claus Matzinger "] 6 | 7 | [dependencies] 8 | rand = "^0.5" -------------------------------------------------------------------------------- /Chapter19/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = '2018' 3 | name = "ch9" 4 | version = "0.1.0" 5 | authors = ["Claus Matzinger "] 6 | 7 | [dependencies] 8 | rand = "^0.5" -------------------------------------------------------------------------------- /Chapter20/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = '2018' 3 | name = "ch10" 4 | version = "0.1.0" 5 | authors = ["Claus Matzinger "] 6 | 7 | [dependencies] 8 | rand = "^0.5" -------------------------------------------------------------------------------- /Chapter21/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = '2018' 3 | name = "ch11" 4 | version = "0.1.0" 5 | authors = ["Claus Matzinger "] 6 | 7 | [dependencies] 8 | rand = "^0.5" -------------------------------------------------------------------------------- /Chapter02/workspace_demo/my_crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my_crate" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter03/bench_example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bench_example" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter04/trait_bound_basics.rs: -------------------------------------------------------------------------------- 1 | // trait_bounds_basics.rs 2 | 3 | fn add_thing(fst: T, snd: T) { 4 | let _ = fst + snd; 5 | } 6 | 7 | fn main() { 8 | add_thing(2, 2); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/into_map/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "into_map" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter03/integration_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "integration_test" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /Chapter05/buffer_overflow.c: -------------------------------------------------------------------------------- 1 | // buffer_overflow.c 2 | 3 | int main() { 4 | char buf[3]; 5 | buf[0] = 'a'; 6 | buf[1] = 'b'; 7 | buf[2] = 'c'; 8 | buf[3] = 'd'; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter07/safe_arithmetic.rs: -------------------------------------------------------------------------------- 1 | // safe_arithmetic.rs 2 | 3 | fn main() { 4 | let foo: u32 = 5; 5 | let bar: i32 = 6; 6 | let difference = foo - bar; 7 | println!("{}", difference); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/c_from_rust/build.rs: -------------------------------------------------------------------------------- 1 | // c_from_rust/build.rs 2 | 3 | fn main() { 4 | cc::Build::new() 5 | .file("mystrlen.c") 6 | .static_flag(true) 7 | .compile("mystrlen"); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/native_counter/main.js: -------------------------------------------------------------------------------- 1 | // native_counter/main.js 2 | 3 | var count_words_func = require('.'); 4 | var wc = count_words_func("A test text to test native module", "test"); 5 | console.log(wc); 6 | -------------------------------------------------------------------------------- /Chapter05/exclusive_borrow.rs: -------------------------------------------------------------------------------- 1 | // exclusive_borrow.rs 2 | 3 | fn main() { 4 | let mut a = String::from("Owned string"); 5 | let a_ref = &mut a; 6 | a_ref.push('!'); 7 | println!("{}", a); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/recursive_type.rs: -------------------------------------------------------------------------------- 1 | // recursive_type.rs 2 | 3 | struct Node { 4 | data: u32, 5 | next: Option 6 | } 7 | 8 | fn main() { 9 | let node = Node {data: 2, next: None}; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/fn_once.rs: -------------------------------------------------------------------------------- 1 | // fn_once.rs 2 | 3 | fn main() { 4 | let a = Box::new(23); 5 | let call_me = || { 6 | let _c = a; 7 | }; 8 | 9 | call_me(); 10 | call_me(); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter10/native_counter/native/build.rs: -------------------------------------------------------------------------------- 1 | extern crate neon_build; 2 | 3 | fn main() { 4 | neon_build::setup(); // must be called in build.rs 5 | 6 | // add project-specific build logic here... 7 | } 8 | -------------------------------------------------------------------------------- /Chapter07/string_range_slice.rs: -------------------------------------------------------------------------------- 1 | // string_range_slice.rs 2 | 3 | fn main() { 4 | let hello = String::from("Strings are cool"); 5 | let first_char = &hello[0..3]; 6 | println!("{:?}", first_char); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter09/http_tester/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "http_tester" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | reqwest = "0.9.5" 9 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/into_map/src/lib.rs: -------------------------------------------------------------------------------- 1 | // into_map_demo/into_map/src/lib.rs 2 | 3 | use std::collections::BTreeMap; 4 | 5 | pub trait IntoMap { 6 | fn into_map(&self) -> BTreeMap; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/c_from_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "c_from_rust" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [build-dependencies] 8 | cc = "1.0" 9 | -------------------------------------------------------------------------------- /Chapter02/workspace_demo/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "app" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "my_crate 0.1.0", 6 | ] 7 | 8 | [[package]] 9 | name = "my_crate" 10 | version = "0.1.0" 11 | 12 | -------------------------------------------------------------------------------- /Chapter04/using_generic_func.rs: -------------------------------------------------------------------------------- 1 | // using_generic_func.rs 2 | 3 | use std::str; 4 | 5 | fn main() { 6 | let num_from_str = str::parse::("34").unwrap(); 7 | println!("Parsed number {}", num_from_str); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/main_result.rs: -------------------------------------------------------------------------------- 1 | // main_result.rs 2 | 3 | fn main() -> Result<(), &'static str> { 4 | let s = vec!["apple", "mango", "banana"]; 5 | let fourth = s.get(4).ok_or("I got only 3 fruits")?; 6 | Ok(()) 7 | } -------------------------------------------------------------------------------- /Chapter05/return_func_ref.rs: -------------------------------------------------------------------------------- 1 | // return_func_ref.rs 2 | 3 | fn get_a_borrowed_value() -> &u8 { 4 | let x = 1; 5 | &x 6 | } 7 | 8 | fn main() { 9 | let value = get_a_borrowed_value(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/stack_basics.rs: -------------------------------------------------------------------------------- 1 | // stack_basics.rs 2 | 3 | fn double_of(b: i32) -> i32 { 4 | let x = 2 * b; 5 | x 6 | } 7 | 8 | fn main() { 9 | let a = 12; 10 | let result = double_of(a); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter06/main_result.rs: -------------------------------------------------------------------------------- 1 | // main_result.rs 2 | 3 | fn main() -> Result<(), &'static str> { 4 | let s = vec!["apple", "mango", "banana"]; 5 | let fourth = s.get(4).ok_or("I got only 3 fruits")?; 6 | Ok(()) 7 | } -------------------------------------------------------------------------------- /Chapter07/const_fn.rs: -------------------------------------------------------------------------------- 1 | // const_fns.rs 2 | 3 | const fn salt(a: u32) -> u32 { 4 | 0xDEADBEEF ^ a 5 | } 6 | 7 | const CHECKSUM: u32 = salt(23); 8 | 9 | fn main() { 10 | println!("{}", CHECKSUM); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter02/mod_within.rs: -------------------------------------------------------------------------------- 1 | // mod_within.rs 2 | 3 | mod food { 4 | struct Cake; 5 | struct Smoothie; 6 | struct Pizza; 7 | } 8 | 9 | use food::Cake; 10 | 11 | fn main() { 12 | let eatable = Cake; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter02/workspace_demo/app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "app" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | my_crate = { path = "../my_crate" } 9 | -------------------------------------------------------------------------------- /Chapter03/integration_test/tests/common.rs: -------------------------------------------------------------------------------- 1 | // integration_test/tests/common.rs 2 | 3 | pub fn setup() { 4 | println!("Setting up fixtures"); 5 | } 6 | 7 | pub fn teardown() { 8 | println!("Tearing down"); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/unsafe_function.rs: -------------------------------------------------------------------------------- 1 | // unsafe_function.rs 2 | 3 | fn get_value(i: *const i32) -> i32 { 4 | unsafe {*i} 5 | } 6 | 7 | fn main() { 8 | let foo = 4 as *const i32; 9 | let _bar = get_value(foo); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter01/if_else.rs: -------------------------------------------------------------------------------- 1 | // if_else.rs 2 | 3 | fn main() { 4 | let rust_is_awesome = true; 5 | if rust_is_awesome { 6 | println!("Indeed"); 7 | } else { 8 | println!("Well, you should try Rust !"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/explicit_lifetimes.rs: -------------------------------------------------------------------------------- 1 | // explicit_lifetimes.rs 2 | 3 | fn foo(a: &str, b: &str) -> &str { 4 | b 5 | } 6 | 7 | fn main() { 8 | let a = "Hello"; 9 | let b = "World"; 10 | let c = foo(a, b); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my_app" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | log4rs = "0.8.0" 8 | log = "0.4" 9 | my_lib = { path = "../my_lib"} -------------------------------------------------------------------------------- /Chapter04/trait_bound_basics_fixed.rs: -------------------------------------------------------------------------------- 1 | // trait_bound_basics_fixed.rs 2 | 3 | use std::ops::Add; 4 | 5 | fn add_thing(fst: T, snd: T) { 6 | let _ = fst + snd; 7 | } 8 | 9 | fn main() { 10 | add_thing(2, 2); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter05/catch_unwind.rs: -------------------------------------------------------------------------------- 1 | // catch_unwind.rs 2 | 3 | use std::panic; 4 | 5 | fn main() { 6 | panic::catch_unwind(|| { 7 | panic!("Panicking!"); 8 | }).ok(); 9 | 10 | println!("Survived that panic."); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter05/making_copy_types.rs: -------------------------------------------------------------------------------- 1 | // making_copy_types.rs 2 | 3 | #[derive(Copy, Debug)] 4 | struct Dummy; 5 | 6 | fn main() { 7 | let a = Dummy; 8 | let b = a; 9 | println!("{:?}", a); 10 | println!("{:?}", b); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter06/catch_unwind.rs: -------------------------------------------------------------------------------- 1 | // catch_unwind.rs 2 | 3 | use std::panic; 4 | 5 | fn main() { 6 | panic::catch_unwind(|| { 7 | panic!("Panicking!"); 8 | }).ok(); 9 | 10 | println!("Survived that panic."); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/refutable_pattern.rs: -------------------------------------------------------------------------------- 1 | // refutable_pattern.rs 2 | 3 | enum Container { 4 | Item(u64), 5 | Empty 6 | } 7 | 8 | fn main() { 9 | let mut item = Container::Item(56); 10 | let Container::Item(it) = item; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter10/word_suffix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "word_suffix" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | pyo3 = "0.4" 8 | 9 | [lib] 10 | crate-type = ["cdylib"] 11 | -------------------------------------------------------------------------------- /Chapter04/generic_function.rs: -------------------------------------------------------------------------------- 1 | // generic_function.rs 2 | 3 | fn give_me(value: T) { 4 | let _ = value; 5 | } 6 | 7 | fn main() { 8 | let a = "generics"; 9 | let b = 1024; 10 | give_me(a); 11 | give_me(b); 12 | } 13 | -------------------------------------------------------------------------------- /Chapter04/impl_trait_syntax.rs: -------------------------------------------------------------------------------- 1 | // impl_trait_syntax.rs 2 | 3 | use std::fmt::Display; 4 | 5 | fn show_me(val: impl Display) { 6 | println!("{}", val); 7 | } 8 | 9 | fn main() { 10 | show_me("Trait bounds are awesome"); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/function_types.rs: -------------------------------------------------------------------------------- 1 | // function_types.rs 2 | 3 | fn add_two(a: u32, b: u32) -> u32 { 4 | a + b 5 | } 6 | 7 | fn main() { 8 | let my_func = add_two; 9 | let res = my_func(3, 4); 10 | println!("{:?}", res); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/type_inference_iterator.rs: -------------------------------------------------------------------------------- 1 | // type_inference_iterator.rs 2 | 3 | use std::fs::File; 4 | use std::io::Read; 5 | 6 | fn main() { 7 | let file = File::open("foo.txt").unwrap(); 8 | let bytes = file.bytes().collect(); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/edit_distance/examples/basic.rs: -------------------------------------------------------------------------------- 1 | 2 | extern crate edit_distance; 3 | use edit_distance::levenshtein_safe; 4 | 5 | fn main() { 6 | let a = "foo"; 7 | let b = "fooo"; 8 | assert_eq!(1, levenshtein_safe(a, b)); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/edit_distance/src/bindings.rs: -------------------------------------------------------------------------------- 1 | /* automatically generated by rust-bindgen */ 2 | 3 | extern "C" { pub fn levenshtein ( a : * const :: std :: os :: raw :: c_char , b : * const :: std :: os :: raw :: c_char ) -> :: std :: os :: raw :: c_uint ; } -------------------------------------------------------------------------------- /Chapter10/rust_from_c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_from_c" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [lib] 8 | name = "stringutils" 9 | crate-type = ["cdylib"] 10 | -------------------------------------------------------------------------------- /Chapter01/functions.rs: -------------------------------------------------------------------------------- 1 | // functions.rs 2 | 3 | fn add(a: u64, b: u64) -> u64 { 4 | a + b 5 | } 6 | 7 | fn main() { 8 | let a: u64 = 17; 9 | let b = 3; 10 | let result = add(a, b); 11 | println!("Result {}", result); 12 | } 13 | -------------------------------------------------------------------------------- /Chapter04/let_pattern_wrapper.rs: -------------------------------------------------------------------------------- 1 | // let_pattern_wrapper.rs 2 | 3 | fn main() { 4 | let mut return_val = Some(0u64); 5 | let success = if let Some(0) = return_val { 6 | true 7 | } else { 8 | false 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/rust_from_c/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int32_t compare_str(const char* value, const char* substr); 5 | 6 | int main() { 7 | printf("%d\n", compare_str("amanda", "brian")); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter01/greet.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | let name = env::args().skip(1).next(); 5 | match name { 6 | Some(n) => println!("Hi there ! {}", n), 7 | None => panic!("Didn't receive any name ?"), 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter01/loops.rs: -------------------------------------------------------------------------------- 1 | // loops.rs 2 | 3 | fn main() { 4 | let mut x = 1024; 5 | loop { 6 | if x < 0 { 7 | break; 8 | } 9 | println!("{} more runs to go", x); 10 | x -= 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter05/borrowing_basics.rs: -------------------------------------------------------------------------------- 1 | // ownership_basics.rs 2 | 3 | #[derive(Debug)] 4 | struct Foo; 5 | 6 | fn main() { 7 | let foo = Foo; 8 | let bar = &foo; 9 | println!("Foo is {:?}", foo); 10 | println!("Bar is {:?}", bar); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter05/making_copy_types_fixed.rs: -------------------------------------------------------------------------------- 1 | // making_copy_types.rs 2 | 3 | #[derive(Copy, Clone, Debug)] 4 | struct Dummy; 5 | 6 | fn main() { 7 | let a = Dummy; 8 | let b = a; 9 | println!("{:?}", a); 10 | println!("{:?}", b); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter10/both_true_false.c: -------------------------------------------------------------------------------- 1 | // both_true_false.c 2 | 3 | int main(void) { 4 | bool var; 5 | if (var) { 6 | fputs("var is true!\n"); 7 | } 8 | if (!var) { 9 | fputs("var is false!\n"); 10 | } 11 | return 0; 12 | } -------------------------------------------------------------------------------- /Chapter13/linksnap/test_server.sh: -------------------------------------------------------------------------------- 1 | 2 | curl --header "Content-Type: application/json" \ 3 | --request POST \ 4 | --data '{"title":"creativcoder blog","url":"https://creativcoder.github.io"}' \ 5 | 127.0.0.1:8080/add 6 | 7 | curl 127.0.0.1:8080/links 8 | -------------------------------------------------------------------------------- /Chapter01/if_assign.rs: -------------------------------------------------------------------------------- 1 | // if_assign.rs 2 | 3 | fn main() { 4 | 5 | let result = if 1 == 2 { 6 | "Wait, what ?" 7 | } else { 8 | "Rust makes sense" 9 | }; 10 | 11 | println!("You know what ? {}.", result); 12 | } 13 | -------------------------------------------------------------------------------- /Chapter03/panic_test.rs: -------------------------------------------------------------------------------- 1 | // panic_test.rs 2 | 3 | // compile in test mode: `rustc --test panic_test.rs` 4 | // run tests using: `./panic_test` 5 | 6 | #[test] 7 | #[should_panic] 8 | fn this_panics() { 9 | panic!("Succeeded in failing!"); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter08/actor_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "actor_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | actix = "0.7.9" 9 | futures = "0.1.25" 10 | tokio = "0.1.15" 11 | -------------------------------------------------------------------------------- /Chapter08/thread_basics.rs: -------------------------------------------------------------------------------- 1 | // thread_basics.rs 2 | 3 | use std::thread; 4 | 5 | fn main() { 6 | thread::spawn(|| { 7 | println!("Thread!"); 8 | "Much concurrent, such wow!".to_string() 9 | }); 10 | print!("Hello "); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter11/slog_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "slog_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | rand = "0.5.5" 8 | slog = "2.4.1" 9 | slog-async = "2.3.0" 10 | slog-json = "2.2.0" 11 | -------------------------------------------------------------------------------- /Chapter01/if_else_no_value.rs: -------------------------------------------------------------------------------- 1 | // if_else_no_value.rs 2 | 3 | fn main() { 4 | let result = if 1 == 2 { 5 | "Nothing makes sense"; 6 | } else { 7 | "Sanity reigns"; 8 | }; 9 | 10 | println!("Result of computation: {:?}", result); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter04/impl_trait_closure.rs: -------------------------------------------------------------------------------- 1 | // impl_trait_closure.rs 2 | 3 | fn lazy_adder(a:u32, b: u32) -> impl Fn() -> u32 { 4 | move || a + b 5 | } 6 | 7 | fn main() { 8 | let add_later = lazy_adder(1024, 2048); 9 | println!("{:?}", add_later()); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter04/trait_bounds_types.rs: -------------------------------------------------------------------------------- 1 | 2 | // trait_bounds_types.rs 3 | 4 | use std::fmt::Display; 5 | 6 | struct Foo { 7 | bar: T 8 | } 9 | 10 | // or 11 | 12 | struct Bar where F: Display { 13 | inner: F 14 | } 15 | 16 | fn main() {} 17 | -------------------------------------------------------------------------------- /Chapter05/ownership_basics.rs: -------------------------------------------------------------------------------- 1 | // ownership_basics.rs 2 | 3 | #[derive(Debug)] 4 | struct Foo(u32); 5 | 6 | fn main() { 7 | let foo = Foo(2048); 8 | let bar = foo; 9 | println!("Foo is {:?}", foo); 10 | println!("Bar is {:?}", bar); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter05/ownership_closures.rs: -------------------------------------------------------------------------------- 1 | // ownership_closures.rs 2 | 3 | #[derive(Debug)] 4 | struct Foo; 5 | 6 | fn main() { 7 | let a = Foo; 8 | 9 | let closure = || { 10 | let b = a; 11 | }; 12 | 13 | println!("{:?}", a); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter07/fn_closure.rs: -------------------------------------------------------------------------------- 1 | // fn_closure.rs 2 | 3 | fn main() { 4 | let a = String::from("Hey!"); 5 | let fn_closure = || { 6 | println!("Closure says: {}", a); 7 | }; 8 | fn_closure(); 9 | println!("Main says: {}", a); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/fn_mut_closure.rs: -------------------------------------------------------------------------------- 1 | // fn_mut_closure.rs 2 | 3 | fn main() { 4 | let mut a = String::from("FnMut closure"); 5 | let mut mut_closure = || { 6 | a.push('!'); 7 | println!("{:?}", a); 8 | }; 9 | mut_closure(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/loop_expr.rs: -------------------------------------------------------------------------------- 1 | // loop_expr.rs 2 | 3 | fn main() { 4 | let mut i = 0; 5 | let counter = loop { 6 | i += 1; 7 | if i == 10 { 8 | break i; 9 | } 10 | }; 11 | 12 | println!("{}", counter); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter01/arrays.rs: -------------------------------------------------------------------------------- 1 | // arrays.rs 2 | 3 | fn main() { 4 | let numbers: [u8; 10] = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]; 5 | let floats = [0.1f64, 0.2, 0.3]; 6 | 7 | println!("Number: {}", numbers[5]); 8 | println!("Float: {}", floats[2]); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter01/function_mut.rs: -------------------------------------------------------------------------------- 1 | // function_mut.rs 2 | 3 | fn increase_by(mut val: u32, how_much: u32) { 4 | val += how_much; 5 | println!("You made {} points", val); 6 | } 7 | 8 | fn main() { 9 | let score = 2048; 10 | increase_by(score, 30); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter01/tuples.rs: -------------------------------------------------------------------------------- 1 | // tuples.rs 2 | 3 | fn main() { 4 | let num_and_str: (u8, &str) = (40, "Have a good day!"); 5 | println!("{:?}", num_and_str); 6 | let (num, string) = num_and_str; 7 | println!("From tuple: Number: {}, String: {}", num, string); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/logic_gates/README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Build Status](https://travis-ci.org/creativcoder/logic_gates.svg?branch=master)](https://travis-ci.org/creativcoder/logic_gates) 3 | 4 | This is a sample repository for Travis and Rust demo for Chapter 3 of Mastering Rust 2nd Edition 5 | -------------------------------------------------------------------------------- /Chapter05/explicit_copy.rs: -------------------------------------------------------------------------------- 1 | // explicit_copy.rs 2 | 3 | #[derive(Clone, Debug)] 4 | struct Dummy { 5 | items: u32 6 | } 7 | 8 | fn main() { 9 | let a = Dummy { items: 54 }; 10 | let b = a.clone(); 11 | println!("a: {:?}, b: {:?}", a, b); 12 | } 13 | -------------------------------------------------------------------------------- /Chapter08/thread_read.rs: -------------------------------------------------------------------------------- 1 | // thread_read.rs 2 | 3 | use std::thread; 4 | 5 | fn main() { 6 | let nums = vec![0, 1, 2, 3, 4]; 7 | for n in 0..5 { 8 | thread::spawn(|| { 9 | println!("{}", nums[n]); 10 | }); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter10/edit_distance/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "edit_distance" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | build = "build.rs" 6 | edition = "2018" 7 | 8 | [build-dependencies] 9 | bindgen = "0.43.0" 10 | cc = "1.0" 11 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | // log4rs_demo/my_lib/lib.rs 2 | 3 | #[macro_use] 4 | extern crate log; 5 | 6 | pub struct Config; 7 | 8 | impl Config { 9 | pub fn load_global_config() { 10 | debug!("Configuration files loaded"); 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter13/shorten/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "shorten" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | quicli = "0.4" 9 | structopt = "0.2" 10 | reqwest = "0.9" 11 | serde = "1" 12 | -------------------------------------------------------------------------------- /Chapter07/serde_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | serde = "1.0.84" 9 | serde_derive = "1.0.84" 10 | serde_json = "1.0.36" 11 | -------------------------------------------------------------------------------- /Chapter03/silly_loop.rs: -------------------------------------------------------------------------------- 1 | // silly_loop.rs 2 | 3 | pub fn silly_loop() { 4 | for _ in 1..1_000_000_000 {}; 5 | } 6 | 7 | #[cfg(test)] 8 | mod tests { 9 | #[test] 10 | #[ignore] 11 | pub fn test_silly_loop() { 12 | ::silly_loop(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter04/generic_struct_impl.rs: -------------------------------------------------------------------------------- 1 | // generic_struct_impl.rs 2 | 3 | struct Container { 4 | item: T 5 | } 6 | 7 | impl Container { 8 | fn new(item: T) -> Self { 9 | Container { item } 10 | } 11 | } 12 | 13 | fn main() { 14 | // stuff 15 | } 16 | -------------------------------------------------------------------------------- /Chapter04/impl_trait_both.rs: -------------------------------------------------------------------------------- 1 | // impl_trait_both.rs 2 | 3 | use std::fmt::Display; 4 | 5 | fn surround_with_braces(val: impl Display) -> impl Display { 6 | format!("{{{}}}", val) 7 | } 8 | 9 | fn main() { 10 | println!("{}", surround_with_braces("Hello")); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "into_map_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | into_map = { path = "into_map" } 9 | into_map_derive = { path = "into_map_derive" } 10 | -------------------------------------------------------------------------------- /Chapter12/rudis_sync/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rudis_sync" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | lazy_static = "1.2.0" 9 | resp = { git = "https://github.com/creativcoder/resp" } 10 | 11 | -------------------------------------------------------------------------------- /Chapter07/borrowed_strings.rs: -------------------------------------------------------------------------------- 1 | // borrowed_strings.rs 2 | 3 | fn get_str_literal() -> &'static str { 4 | "from function" 5 | } 6 | 7 | fn main() { 8 | let my_str = "This is borrowed"; 9 | let from_func = get_str_literal(); 10 | println!("{} {}", my_str, from_func); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter08/threads_shared_owner.rs: -------------------------------------------------------------------------------- 1 | 2 | // shared_owner_threads.rs 3 | 4 | use std::thread; 5 | 6 | struct Payload { 7 | data: Rc 8 | } 9 | 10 | fn main() { 11 | let p = Payload { 12 | data: Rc::new(0) 13 | }; 14 | for i in 0..10 { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter09/c_macros_rust.rs: -------------------------------------------------------------------------------- 1 | // c_macros_rust.rs 2 | 3 | macro_rules! switch { 4 | ($a:expr, $b:expr) => { 5 | temp = $b; $b = $a; $a = temp; 6 | }; 7 | } 8 | 9 | fn main() { 10 | let x = 1; 11 | let y = 2; 12 | let temp = 3; 13 | switch!(x, y); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter01/variables.rs: -------------------------------------------------------------------------------- 1 | // variables.rs 2 | 3 | fn main() { 4 | let target = "world"; 5 | let mut greeting = "Hello"; 6 | println!("{}, {}", greeting, target); 7 | greeting = "How are you doing"; 8 | target = "mate"; 9 | println!("{}, {}", greeting, target); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter03/logic_gates/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | matrix: 7 | allow_failures: 8 | - rust: nightly 9 | fast_finish: true 10 | cache: cargo 11 | 12 | script: 13 | - cargo build --verbose --all 14 | - cargo test --verbose --all 15 | -------------------------------------------------------------------------------- /Chapter05/using_options.rs: -------------------------------------------------------------------------------- 1 | // using_options.rs 2 | 3 | use std::collections::HashMap; 4 | fn main() { 5 | let mut map = HashMap::new(); 6 | map.insert("one", 1); 7 | map.insert("two", 2); 8 | 9 | let value = map.get("one"); 10 | let incremented_value = value + 1; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter06/using_options.rs: -------------------------------------------------------------------------------- 1 | // using_options.rs 2 | 3 | use std::collections::HashMap; 4 | fn main() { 5 | let mut map = HashMap::new(); 6 | map.insert("one", 1); 7 | map.insert("two", 2); 8 | 9 | let value = map.get("one"); 10 | let incremented_value = value + 1; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter01/first_program.rs: -------------------------------------------------------------------------------- 1 | 2 | // first_program.rs 3 | 4 | use std::env; 5 | 6 | fn main() { 7 | let name = env::args().skip(1).next(); 8 | match name { 9 | Some(name) => println!("Hi there ! {}", name), 10 | None => panic!("Didn't receive any name ?") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/log/my_lib.log: -------------------------------------------------------------------------------- 1 | 2018-11-26T03:29:55.683977819+05:30 - Configuration files loaded 2 | 2018-11-26T03:52:21.548536495+05:30 - Configuration files loaded 3 | 2018-11-26T03:52:49.172077330+05:30 - Configuration files loaded 4 | 2018-11-26T03:52:52.052438996+05:30 - Configuration files loaded 5 | -------------------------------------------------------------------------------- /Chapter08/thread_moves.rs: -------------------------------------------------------------------------------- 1 | // thread_moves.rs 2 | 3 | use std::thread; 4 | 5 | fn main() { 6 | let my_str = String::from("Damn you borrow checker!"); 7 | let _ = thread::spawn(move || { 8 | println!("In thread: {}", my_str); 9 | }); 10 | println!("In main: {}", my_str); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter01/strings.rs: -------------------------------------------------------------------------------- 1 | // strings.rs 2 | 3 | fn main() { 4 | let question = "How are you ?"; // a &str type 5 | let person: String = "Bob".to_string(); 6 | let namaste = String::from("नमस्ते"); // unicodes yay! 7 | 8 | println!("{}! {} {}", namaste, question, person); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter07/const_fn_file.rs: -------------------------------------------------------------------------------- 1 | // const_fn_file.rs 2 | 3 | const fn read_header(a: &[u8]) -> (u8, u8, u8, u8) { 4 | (a[0], a[1], a[2], a[3]) 5 | } 6 | 7 | const FILE_HEADER: (u8,u8,u8,u8) = read_header(include_bytes!("./const_fn_file.rs")); 8 | 9 | fn main() { 10 | println!("{:?}", FILE_HEADER); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/nested_imports.rs: -------------------------------------------------------------------------------- 1 | // nested_imports.rs 2 | 3 | use std::sync::{Arc, Mutex, mpsc::{channel, Sender, Receiver}}; 4 | 5 | fn consume(_tx: Sender<()>, _rx: Receiver<()>) { } 6 | 7 | fn main() { 8 | let _ = Arc::new(Mutex::new(40)); 9 | let (tx, rx) = channel(); 10 | consume(tx, rx); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/criterion_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "criterion_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dev-dependencies] 10 | criterion = "0.1.2" 11 | 12 | [[bench]] 13 | name = "fibonacci" 14 | harness = false 15 | -------------------------------------------------------------------------------- /Chapter07/match_ref.rs: -------------------------------------------------------------------------------- 1 | // match_ref.rs 2 | 3 | struct Person(String); 4 | 5 | fn main() { 6 | let a = Person("Richard Feynman".to_string()); 7 | match a { 8 | Person(&name) => println!("{} was a great physicist !", name), 9 | _ => panic!("Oh no !") 10 | } 11 | 12 | let b = a; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter08/thread_mut.rs: -------------------------------------------------------------------------------- 1 | // thread_mut.rs 2 | 3 | use std::thread; 4 | use std::sync::Arc; 5 | 6 | fn main() { 7 | let mut nums = Arc::new(vec![]); 8 | for n in 0..5 { 9 | let mut ns = nums.clone(); 10 | thread::spawn(move || { 11 | nums.push(n); 12 | }); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter09/c_macros.c: -------------------------------------------------------------------------------- 1 | // c_macros.c 2 | 3 | #include 4 | 5 | #define SWITCH(a, b) { temp = b; b = a; a = temp; } 6 | 7 | int main() { 8 | int x=1; 9 | int y=2; 10 | int temp = 3; 11 | 12 | SWITCH(x, y); 13 | printf("x is now %d. y is now %d. temp is now %d\n", x, y, temp); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter04/trait_bound_intro.rs: -------------------------------------------------------------------------------- 1 | // trait_bounds_intro.rs 2 | 3 | struct Game; 4 | struct Enemy; 5 | struct Hero; 6 | 7 | impl Game { 8 | fn load(&self, entity: T) { 9 | entity.init(); 10 | } 11 | } 12 | 13 | fn main() { 14 | let game = Game; 15 | game.load(Enemy); 16 | game.load(Hero); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter07/destructure_enum.rs: -------------------------------------------------------------------------------- 1 | // destructure_enum.rs 2 | 3 | enum Container { 4 | Item(u64), 5 | Empty 6 | } 7 | 8 | fn main() { 9 | let maybe_item = Container::Item(0u64); 10 | let has_item = if let Container::Item(0) = maybe_item { 11 | true 12 | } else { 13 | false 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter05/using_options_unwrap.rs: -------------------------------------------------------------------------------- 1 | // using_options_unwrap.rs 2 | 3 | use std::collections::HashMap; 4 | 5 | fn main() { 6 | let mut map = HashMap::new(); 7 | map.insert("one", 1); 8 | map.insert("two", 2); 9 | let incremented_value = map.get("three").unwrap() + 1; 10 | println!("{}", incremented_value); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter06/create_result_fixed.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let _my_result: Result<_, ()> = Ok(64); 3 | // or 4 | let _my_result = Ok::<_, ()>(64); 5 | 6 | // similarly we create Err variants 7 | 8 | let _my_err = Err::<(), f32>(345.3); 9 | let _other_err: Result = Err("Wait, what ?".to_string()); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter06/using_options_unwrap.rs: -------------------------------------------------------------------------------- 1 | // using_options_unwrap.rs 2 | 3 | use std::collections::HashMap; 4 | 5 | fn main() { 6 | let mut map = HashMap::new(); 7 | map.insert("one", 1); 8 | map.insert("two", 2); 9 | let incremented_value = map.get("three").unwrap() + 1; 10 | println!("{}", incremented_value); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/string_slices_func.rs: -------------------------------------------------------------------------------- 1 | // string_slices_func.rs 2 | 3 | fn say_hello(to_whom: &str) { 4 | println!("Hey {}!", to_whom) 5 | } 6 | 7 | fn main() { 8 | let string_slice: &'static str = "you"; 9 | let string: String = string_slice.into(); 10 | say_hello(string_slice); 11 | say_hello(&string); 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/env_logger_demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "env_logger_demo" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | 6 | [dependencies] 7 | user_auth = { path = "../user_auth" } 8 | log = { version = "0.4.6", features = ["release_max_level_error", "max_level_trace"] } 9 | env_logger = "0.6.0" 10 | -------------------------------------------------------------------------------- /Chapter05/result_basics.rs: -------------------------------------------------------------------------------- 1 | // result_basics.rs 2 | 3 | use std::fs::File; 4 | use std::io::Read; 5 | use std::path::Path; 6 | 7 | fn main() { 8 | let path = Path::new("data.txt"); 9 | let file = File::open(&path); 10 | let mut s = String::new(); 11 | file.read_to_string(&mut s); 12 | println!("Message: {}", s); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter06/result_basics.rs: -------------------------------------------------------------------------------- 1 | // result_basics.rs 2 | 3 | use std::fs::File; 4 | use std::io::Read; 5 | use std::path::Path; 6 | 7 | fn main() { 8 | let path = Path::new("data.txt"); 9 | let file = File::open(&path); 10 | let mut s = String::new(); 11 | file.read_to_string(&mut s); 12 | println!("Message: {}", s); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/box_basics.rs: -------------------------------------------------------------------------------- 1 | // box_basics.rs 2 | 3 | fn box_ref(b: T) -> Box { 4 | let a = b; 5 | Box::new(a) 6 | } 7 | 8 | #[derive(Debug)] 9 | struct Foo; 10 | 11 | fn main() { 12 | let boxed_one = Box::new(Foo); 13 | let unboxed_one = boxed_one; 14 | println!("{:?}", boxed_one); 15 | // box_ref(unboxed_one); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter09/print_formatting.rs: -------------------------------------------------------------------------------- 1 | // print_formatting.rs 2 | 3 | use std::collections::HashMap; 4 | 5 | fn main() { 6 | let a = 3669732608; 7 | println!("{:p}", a); 8 | println!("{:x}", a); 9 | 10 | // pretty printing 11 | let mut map = HashMap::new(); 12 | map.insert("foo", "bar"); 13 | println!("{:#?}", map); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter05/ownership_functions.rs: -------------------------------------------------------------------------------- 1 | // ownership_functions.rs 2 | 3 | fn take_the_n(n: u8) { } 4 | 5 | fn take_the_s(s: String) { } 6 | 7 | fn main() { 8 | let n = 5; 9 | let s = String::from("string"); 10 | 11 | take_the_n(n); 12 | take_the_s(s); 13 | 14 | println!("n is {}", n); 15 | println!("s is {}", s); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter02/imgtool/src/main.rs: -------------------------------------------------------------------------------- 1 | // imgtool/src/main.rs 2 | 3 | use std::env; 4 | use std::path::Path; 5 | 6 | fn main() { 7 | let image_path = env::args().skip(1).next().unwrap(); 8 | let path = Path::new(&image_path); 9 | let img = image::open(path).unwrap(); 10 | let rotated = img.rotate90(); 11 | rotated.save(path).unwrap(); 12 | } 13 | -------------------------------------------------------------------------------- /Chapter04/using_generic_vec.rs: -------------------------------------------------------------------------------- 1 | // using_generic_vec.rs 2 | 3 | fn main() { 4 | // providing a type 5 | let v1: Vec = Vec::new(); 6 | 7 | // or calling method 8 | let mut v2 = Vec::new(); 9 | v2.push(2); // v2 is now Vec 10 | 11 | // or using turbofish 12 | let v3 = Vec::::new(); // not so readable 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/ownership_methods.rs: -------------------------------------------------------------------------------- 1 | // ownership_methods.rs 2 | 3 | struct Item(u32); 4 | 5 | impl Item { 6 | fn new() -> Self { 7 | Item(1024) 8 | } 9 | 10 | fn take_item(self) { 11 | // does nothing 12 | } 13 | } 14 | 15 | fn main() { 16 | let it = Item::new(); 17 | it.take_item(); 18 | println!("{}", it.0); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/unsafe_trait_and_impl.rs: -------------------------------------------------------------------------------- 1 | // unsafe_trait_and_impl.rs 2 | 3 | struct MyType; 4 | 5 | unsafe trait UnsafeTrait { 6 | unsafe fn unsafe_function(); 7 | } 8 | 9 | trait SafeTrait { 10 | unsafe fn unsafe_method(&self); 11 | } 12 | 13 | unsafe impl UnsafeTrait for MyType { 14 | unsafe fn unsafe_function() { } 15 | } 16 | 17 | fn main() {} 18 | -------------------------------------------------------------------------------- /Chapter13/hyperurl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hyperurl" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | hyper = "0.12.17" 9 | serde_json = "1.0.33" 10 | futures = "0.1.25" 11 | lazy_static = "1.2.0" 12 | rust-crypto = "0.2.36" 13 | pretty_env_logger = "0.3" 14 | log = "0.4" 15 | -------------------------------------------------------------------------------- /Chapter05/cell.rs: -------------------------------------------------------------------------------- 1 | // cell.rs 2 | 3 | use std::cell::Cell; 4 | 5 | #[derive(Debug)] 6 | struct Bag { 7 | item: Box 8 | } 9 | 10 | fn main() { 11 | let bag = Cell::new(Bag { item: Box::new(1) }); 12 | let hand1 = &bag; 13 | let hand2 = &bag; 14 | hand1.set(Bag { item: Box::new(2)}); 15 | hand2.set(Bag { item: Box::new(3)}); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/my_app/src/main.rs: -------------------------------------------------------------------------------- 1 | 2 | #[macro_use] 3 | extern crate log; 4 | extern crate log4rs; 5 | 6 | extern crate my_lib; 7 | 8 | use my_lib::Config; 9 | 10 | fn main() { 11 | log4rs::init_file("config/log4rs.yaml", Default::default()).unwrap(); 12 | error!("Sample app v{}", env!("CARGO_PKG_VERSION")); 13 | Config::load_global_config(); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/rudis_async/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rudis_async" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | tokio = "0.1.13" 9 | futures = "0.1.25" 10 | lazy_static = "1.2.0" 11 | resp = { git = "https://github.com/creativcoder/resp" } 12 | tokio-codec = "0.1.1" 13 | bytes = "0.4.11" 14 | -------------------------------------------------------------------------------- /Chapter03/ignored_test.rs: -------------------------------------------------------------------------------- 1 | // silly_loop.rs 2 | 3 | // compile in test mode: `rustc --test ignored_test.rs` 4 | // run tests using: `./ignored_test` 5 | 6 | pub fn silly_loop() { 7 | for _ in 1..1_000_000_000 {}; 8 | } 9 | 10 | #[cfg(test)] 11 | mod tests { 12 | #[test] 13 | #[ignore] 14 | pub fn test_silly_loop() { 15 | ::silly_loop(); 16 | } 17 | } -------------------------------------------------------------------------------- /Chapter04/generic_struct.rs: -------------------------------------------------------------------------------- 1 | // generic_struct.rs 2 | 3 | struct Container { 4 | item: T 5 | } 6 | 7 | impl Container { 8 | fn new(item: T) -> Self { 9 | Container { item } 10 | } 11 | } 12 | 13 | impl Container { 14 | fn sum(item: u32) -> Self { 15 | Container { item } 16 | } 17 | } 18 | 19 | fn main() { 20 | // todo 21 | } -------------------------------------------------------------------------------- /Chapter09/into_map_demo/into_map_derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "into_map_derive" 3 | version = "0.1.0" 4 | authors = ["Rahul Sharma "] 5 | edition = "2018" 6 | 7 | [lib] 8 | proc-macro = true 9 | 10 | [dependencies] 11 | syn = { version = "0.15.22", features = ["extra-traits"] } 12 | quote = "0.6.10" 13 | into_map = { path="../into_map" } 14 | -------------------------------------------------------------------------------- /Chapter01/for_loops.rs: -------------------------------------------------------------------------------- 1 | // for_loops.rs 2 | 3 | fn main() { 4 | // does not include 10 5 | print!("Normal ranges: "); 6 | for i in 0..10 { 7 | print!("{},", i); 8 | } 9 | 10 | println!(); // just a newline 11 | print!("Inclusive ranges: "); 12 | // counts till 10 13 | for i in 0..=10 { 14 | print!("{},", i); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter03/integration_test/tests/sum.rs: -------------------------------------------------------------------------------- 1 | // integration_test/tests/sum.rs 2 | 3 | use integration_test::sum; 4 | 5 | mod common; 6 | 7 | use common::{setup, teardown}; 8 | 9 | #[test] 10 | fn sum_test() { 11 | assert_eq!(sum(6, 8), 14); 12 | } 13 | 14 | #[test] 15 | fn test_with_fixture() { 16 | setup(); 17 | assert_eq!(sum(7, 14), 21); 18 | teardown(); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/ufcs.rs: -------------------------------------------------------------------------------- 1 | // ufcs.rs 2 | 3 | trait Driver { 4 | fn drive(&self) { 5 | println!("Driver's driving!"); 6 | } 7 | } 8 | 9 | struct MyCar; 10 | 11 | impl MyCar { 12 | fn drive(&self) { 13 | println!("I'm driving!"); 14 | } 15 | } 16 | 17 | impl Driver for MyCar {} 18 | 19 | fn main() { 20 | let car = MyCar; 21 | car.drive(); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter05/lifetime_bounds.rs: -------------------------------------------------------------------------------- 1 | // lifetime_bounds.rs 2 | 3 | enum Level { 4 | Error 5 | } 6 | 7 | struct Logger<'a>(&'a str, Level); 8 | 9 | fn configure_logger(_t: T) where T: Send + 'static { 10 | // configure the logger here 11 | } 12 | 13 | fn main() { 14 | let name = "Global"; 15 | let log1 = Logger(name, Level::Error); 16 | configure_logger(log1); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter05/lifetime_subtyping.rs: -------------------------------------------------------------------------------- 1 | // lifetime_subtyping.rs 2 | 3 | struct Decoder<'a, 'b, S, R> { 4 | schema: &'a S, 5 | reader: &'b R 6 | } 7 | 8 | impl<'a, 'b, S, R> Decoder<'a, 'b, S, R> 9 | where 'a: 'b { 10 | 11 | } 12 | 13 | fn main() { 14 | let a: Vec = vec![]; 15 | let b: Vec = vec![]; 16 | let decoder = Decoder {schema: &a, reader: &b}; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter05/using_options_match.rs: -------------------------------------------------------------------------------- 1 | // using_options_match.rs 2 | 3 | use std::collections::HashMap; 4 | fn main() { 5 | let mut map = HashMap::new(); 6 | map.insert("one", 1); 7 | map.insert("two", 2); 8 | let incremented_value = match map.get("one") { 9 | Some(val) => val + 1, 10 | None => 0 11 | }; 12 | println!("{}", incremented_value); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter06/todolist_parser/examples/README.md: -------------------------------------------------------------------------------- 1 | 2 | To see the custom errors, try running the `basics.rs` example by initializing `TodoList` 3 | in one of the following ways: 4 | 5 | * `let todos = TodoList::get_todos("examples/malformed_todo");` - The case where we have a malformed todo. 6 | * `let todos = TodoList::get_todos("examples/todos");` - The case where our `todos` file doesn't exist. 7 | -------------------------------------------------------------------------------- /Chapter06/using_options_match.rs: -------------------------------------------------------------------------------- 1 | // using_options_match.rs 2 | 3 | use std::collections::HashMap; 4 | fn main() { 5 | let mut map = HashMap::new(); 6 | map.insert("one", 1); 7 | map.insert("two", 2); 8 | let incremented_value = match map.get("one") { 9 | Some(val) => val + 1, 10 | None => 0 11 | }; 12 | println!("{}", incremented_value); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter08/thread_basics_join.rs: -------------------------------------------------------------------------------- 1 | // thread_basics_join.rs 2 | 3 | use std::thread; 4 | 5 | fn main() { 6 | let child = thread::spawn(|| { 7 | println!("Thread!"); 8 | String::from("Much concurrent, such wow!") 9 | }); 10 | 11 | print!("Hello "); 12 | let value = child.join().expect("Failed joining child thread"); 13 | println!("{}", value); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter07/type_alias.rs: -------------------------------------------------------------------------------- 1 | // type_alias.rs 2 | 3 | pub struct ParsedPayload { 4 | inner: T 5 | } 6 | 7 | pub struct ParseError { 8 | inner: E 9 | } 10 | 11 | type ParserResult = Result, ParseError>; 12 | 13 | pub fn parse_payload(stream: &[u8]) -> ParserResult { 14 | unimplemented!(); 15 | } 16 | 17 | fn main() { 18 | // todo 19 | } 20 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/src/main.rs: -------------------------------------------------------------------------------- 1 | // into_map_demo/src/main.rs 2 | 3 | use into_map_derive::IntoMap; 4 | 5 | #[derive(IntoMap)] 6 | struct User { 7 | name: String, 8 | id: usize, 9 | active: bool 10 | } 11 | 12 | fn main() { 13 | let my_bar = User { name: "Alice".to_string(), id: 35, active: false }; 14 | let map = my_bar.into_map(); 15 | println!("{:?}", map); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter11/env_logger_demo/src/main.rs: -------------------------------------------------------------------------------- 1 | 2 | #[macro_use] 3 | extern crate log; 4 | extern crate env_logger; 5 | extern crate user_auth; 6 | 7 | use user_auth::User; 8 | 9 | fn main() { 10 | env_logger::init(); 11 | debug!("env logger demo started"); 12 | let user = User::new("bob", "super_sekret"); 13 | user.sign_in("super_secret"); 14 | user.sign_in("super_sekret"); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter05/drop.rs: -------------------------------------------------------------------------------- 1 | // drop.rs 2 | 3 | struct Character { 4 | name: String, 5 | } 6 | 7 | impl Drop for Character { 8 | fn drop(&mut self) { 9 | println!("{} went away", self.name) 10 | } 11 | } 12 | 13 | fn main() { 14 | let steve = Character { 15 | name: "Steve".into(), 16 | }; 17 | let john = Character { 18 | name: "John".into(), 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter13/hyperurl/src/shortener.rs: -------------------------------------------------------------------------------- 1 | // hyperurl/src/shortener.rs 2 | 3 | use crypto::digest::Digest; 4 | use crypto::sha2::Sha256; 5 | 6 | use crate::LISTEN_ADDR; 7 | 8 | pub(crate) fn shorten_url(url: &str) -> String { 9 | let mut sha = Sha256::new(); 10 | sha.input_str(url); 11 | let mut s = sha.result_str(); 12 | s.truncate(5); 13 | format!("{}/{}", LISTEN_ADDR, s) 14 | } 15 | -------------------------------------------------------------------------------- /Chapter05/without_cell.rs: -------------------------------------------------------------------------------- 1 | // without_cell.rs 2 | 3 | use std::cell::Cell; 4 | 5 | #[derive(Debug)] 6 | struct Bag { 7 | item: Box 8 | } 9 | 10 | fn main() { 11 | let mut bag = Cell::new(Bag { item: Box::new(1) }); 12 | let hand1 = &mut bag; 13 | let hand2 = &mut bag; 14 | *hand1 = Cell::new(Bag {item: Box::new(2)}); 15 | *hand2 = Cell::new(Bag {item: Box::new(2)}); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter13/linksnap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linksnap" 3 | version = "0.1.0" 4 | authors = ["creativcoders@gmail.com"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | actix = "0.7" 9 | actix-web = "0.7" 10 | futures = "0.1" 11 | env_logger = "0.5" 12 | bytes = "0.4" 13 | serde = "1.0.80" 14 | serde_json = "1.0.33" 15 | serde_derive = "1.0.80" 16 | url = "1.7.2" 17 | log = "0.4.6" 18 | chrono = "0.4.6" 19 | -------------------------------------------------------------------------------- /Chapter05/lifetime_bounds_short.rs: -------------------------------------------------------------------------------- 1 | // lifetime_bounds_short.rs 2 | 3 | enum Level { 4 | Error 5 | } 6 | 7 | struct Logger<'a>(&'a str, Level); 8 | 9 | fn configure_logger(_t: T) where T: Send + 'static { 10 | // configure the logger here 11 | } 12 | 13 | fn main() { 14 | let other = String::from("Local"); 15 | let log2 = Logger(&other, Level::Error); 16 | configure_logger(&log2); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter01/closures.rs: -------------------------------------------------------------------------------- 1 | // closures.rs 2 | 3 | fn main() { 4 | let doubler = |x| x * 2; 5 | let value = 5; 6 | let twice = doubler(value); 7 | println!("{} doubled is {}", value, twice); 8 | 9 | let big_closure = |b, c| { 10 | let z = b + c; 11 | z * twice 12 | }; 13 | 14 | let some_number = big_closure(1, 2); 15 | println!("Result from closure: {}", some_number); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter05/iterator_invalidation.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::vector v{1, 5, 10, 15, 20}; 8 | 9 | for (auto it=v.begin();it!=v.end();it++) 10 | if ((*it) == 5) 11 | v.push_back(-1); 12 | 13 | for (auto it=v.begin();it!=v.end();it++) 14 | std::cout << (*it) << " "; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter07/unions.rs: -------------------------------------------------------------------------------- 1 | // unions.rs 2 | 3 | #[repr(C)] 4 | union Metric { 5 | rounded: u32, 6 | precise: f32, 7 | } 8 | 9 | fn main() { 10 | let mut a = Metric { rounded: 323 }; 11 | unsafe { 12 | println!("{}", a.rounded); 13 | } 14 | unsafe { 15 | println!("{}", a.precise); 16 | } 17 | a.precise = 33.3; 18 | unsafe { 19 | println!("{}", a.precise); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter08/mutex_basics.rs: -------------------------------------------------------------------------------- 1 | // mutex_basics.rs 2 | 3 | use std::sync::Mutex; 4 | use std::thread; 5 | 6 | fn main() { 7 | let m = Mutex::new(0); 8 | let c = thread::spawn(move || { 9 | { 10 | *m.lock().unwrap() += 1; 11 | } 12 | let updated = *m.lock().unwrap(); 13 | updated 14 | }); 15 | let updated = c.join().unwrap(); 16 | println!("{:?}", updated); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter10/native_counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "native_counter", 3 | "version": "0.1.0", 4 | "description": "A native nodejs module in Rust to count words in a given text", 5 | "main": "lib/index.js", 6 | "author": "Rahul Sharma ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "neon-cli": "^0.2.0" 10 | }, 11 | "scripts": { 12 | "install": "neon build" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter01/match_expression.rs: -------------------------------------------------------------------------------- 1 | // match_expression.rs 2 | 3 | fn req_status() -> u32 { 4 | 200 5 | } 6 | 7 | fn main() { 8 | let status = req_status(); 9 | match status { 10 | 200 => println!("Success"), 11 | 404 => println!("Not Found"), 12 | other => { 13 | println!("Request failed with code: {}", other); 14 | // get response from cache 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter08/thread_rwlock.rs: -------------------------------------------------------------------------------- 1 | // thread_rwlock.rs 2 | 3 | use std::sync::RwLock; 4 | use std::thread; 5 | 6 | fn main() { 7 | let m = RwLock::new(5); 8 | let c = thread::spawn(move || { 9 | { 10 | *m.write().unwrap() += 1; 11 | } 12 | let updated = *m.read().unwrap(); 13 | updated 14 | }); 15 | let updated = c.join().unwrap(); 16 | println!("{:?}", updated); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter05/ownership_functions_back.rs: -------------------------------------------------------------------------------- 1 | // ownership_functions_back.rs 2 | 3 | fn take_the_n(n: u8) { } 4 | 5 | fn take_the_s(s: String) -> String { 6 | println!("inside function: {}", s); 7 | s 8 | } 9 | 10 | fn main() { 11 | let n = 5; 12 | let s = String::from("string"); 13 | 14 | take_the_n(n); 15 | let s = take_the_s(s); 16 | 17 | println!("n is {}", n); 18 | println!("s is {}", s); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter05/borrowing_functions.rs: -------------------------------------------------------------------------------- 1 | // borrowing_functions.rs 2 | 3 | fn take_the_n(n: &mut u8) { 4 | *n += 2; 5 | } 6 | 7 | fn take_the_s(s: &mut String) { 8 | s.push_str("ing"); 9 | } 10 | 11 | fn main() { 12 | let mut n = 5; 13 | let mut s = String::from("Borrow"); 14 | 15 | take_the_n(&mut n); 16 | take_the_s(&mut s); 17 | 18 | println!("n changed to {}", n); 19 | println!("s changed to {}", s); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter08/customize_threads.rs: -------------------------------------------------------------------------------- 1 | // customize_threads.rs 2 | 3 | use std::thread::Builder; 4 | 5 | fn main() { 6 | let my_thread = Builder::new().name("Worker Thread".to_string()) 7 | .stack_size(1024 * 4); 8 | let handle = my_thread.spawn(|| { 9 | panic!("Oops!"); 10 | }); 11 | let child_status = handle.unwrap().join(); 12 | println!("Child status: {:?}", child_status); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter01/slices.rs: -------------------------------------------------------------------------------- 1 | // slices.rs 2 | 3 | fn main() { 4 | let mut numbers: [u8; 4] = [1, 2, 3, 4]; 5 | { 6 | let all: &[u8] = &numbers[..]; 7 | println!("All of them: {:?}", all); 8 | } 9 | 10 | { 11 | let first_two: &mut [u8] = &mut numbers[0..2]; 12 | first_two[0] = 100; 13 | first_two[1] = 99; 14 | } 15 | 16 | println!("Look ma! I can modify through slices: {:?}", numbers); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter03/criterion_demo/benches/fibonacci.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate criterion; 3 | 4 | extern crate criterion_demo; 5 | 6 | use criterion_demo::{slow_fibonacci, fast_fibonacci}; 7 | 8 | use criterion::Criterion; 9 | 10 | fn fibonacci_benchmark(c: &mut Criterion) { 11 | c.bench_function("fibonacci 8", |b| b.iter(|| fast_fibonacci(8))); 12 | } 13 | 14 | criterion_group!(fib_bench, fibonacci_benchmark); 15 | criterion_main!(fib_bench); 16 | -------------------------------------------------------------------------------- /Chapter11/log4rs_demo/config/log4rs.yaml: -------------------------------------------------------------------------------- 1 | # config/log4rs.yaml 2 | 3 | refresh_rate: 5 seconds 4 | 5 | root: 6 | level: error 7 | appenders: 8 | - stdout 9 | 10 | appenders: 11 | stdout: 12 | kind: console 13 | my_lib_append: 14 | kind: file 15 | path: "log/my_lib.log" 16 | encoder: 17 | pattern: "{d} - {m}{n}" 18 | 19 | loggers: 20 | my_lib: 21 | level: debug 22 | appenders: 23 | - my_lib_append 24 | -------------------------------------------------------------------------------- /Chapter05/todolist_parser/examples/basics.rs: -------------------------------------------------------------------------------- 1 | // todolist_parser/examples/basics.rs 2 | 3 | extern crate todolist_parser; 4 | 5 | use todolist_parser::TodoList; 6 | 7 | fn main() { 8 | let todos = TodoList::get_todos("examples/todos"); 9 | match todos { 10 | Ok(list) => println!("{:?}", list), 11 | Err(e) => { 12 | println!("{}", e.description()); 13 | println!("{:?}", e) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter05/using_question_operator.rs: -------------------------------------------------------------------------------- 1 | // using_question_operator.rs 2 | 3 | use std::string::FromUtf8Error; 4 | 5 | fn str_upper_concise(str: Vec) -> Result { 6 | let ret = String::from_utf8(str).map(|s| s.to_uppercase())?; 7 | println!("Conversion succeeded: {}", ret); 8 | Ok(ret) 9 | } 10 | 11 | fn main() { 12 | let valid_str = str_upper_concise(vec![121, 97, 89]); 13 | println!("{:?}", valid_str); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter06/todolist_parser/examples/basics.rs: -------------------------------------------------------------------------------- 1 | // todolist_parser/examples/basics.rs 2 | 3 | extern crate todolist_parser; 4 | 5 | use todolist_parser::TodoList; 6 | 7 | fn main() { 8 | let todos = TodoList::get_todos("examples/todos"); 9 | match todos { 10 | Ok(list) => println!("{:?}", list), 11 | Err(e) => { 12 | println!("{}", e.description()); 13 | println!("{:?}", e) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter06/using_question_operator.rs: -------------------------------------------------------------------------------- 1 | // using_question_operator.rs 2 | 3 | use std::string::FromUtf8Error; 4 | 5 | fn str_upper_concise(str: Vec) -> Result { 6 | let ret = String::from_utf8(str).map(|s| s.to_uppercase())?; 7 | println!("Conversion succeeded: {}", ret); 8 | Ok(ret) 9 | } 10 | 11 | fn main() { 12 | let valid_str = str_upper_concise(vec![121, 97, 89]); 13 | println!("{:?}", valid_str); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter05/ownership_match.rs: -------------------------------------------------------------------------------- 1 | // ownership_match.rs 2 | 3 | #[derive(Debug)] 4 | enum Food { 5 | Cake, 6 | Pizza, 7 | Salad 8 | } 9 | 10 | #[derive(Debug)] 11 | struct Bag { 12 | food: Food 13 | } 14 | 15 | fn main() { 16 | let bag = Bag { food: Food::Cake }; 17 | match bag.food { 18 | Food::Cake => println!("I got cake"), 19 | a => println!("I got {:?}", a) 20 | } 21 | 22 | println!("{:?}", bag); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter05/borrowing_match.rs: -------------------------------------------------------------------------------- 1 | // ownership_match.rs 2 | 3 | #[derive(Debug)] 4 | enum Food { 5 | Cake, 6 | Pizza, 7 | Salad 8 | } 9 | 10 | #[derive(Debug)] 11 | struct Bag { 12 | food: Food 13 | } 14 | 15 | fn main() { 16 | let bag = Bag { food: Food::Cake }; 17 | match bag.food { 18 | Food::Cake => println!("I got cake"), 19 | ref a => println!("I got {:?}", a) 20 | } 21 | 22 | println!("{:?}", bag); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter08/thread_rc.rs: -------------------------------------------------------------------------------- 1 | // thread_rc.rs 2 | 3 | use std::thread; 4 | use std::rc::Rc; 5 | 6 | fn main() { 7 | let nums = Rc::new(vec![0, 1, 2, 3, 4]); 8 | let mut childs = vec![]; 9 | for n in 0..5 { 10 | let ns = nums.clone(); 11 | let c = thread::spawn(|| { 12 | println!("{}", ns[n]); 13 | }); 14 | childs.push(c); 15 | } 16 | 17 | for c in childs { 18 | c.join().unwrap(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter05/panic_unwinding.rs: -------------------------------------------------------------------------------- 1 | // panic_unwinding.rs 2 | 3 | use std::thread; 4 | 5 | fn alice() -> thread::JoinHandle<()> { 6 | thread::spawn(move || { 7 | bob(); 8 | }) 9 | } 10 | 11 | fn bob() { 12 | malice(); 13 | } 14 | 15 | fn malice() { 16 | panic!("malice is panicking!"); 17 | } 18 | 19 | fn main() { 20 | let child = alice(); 21 | let _ = child.join(); 22 | 23 | bob(); 24 | println!("This is unreachable code"); 25 | } 26 | -------------------------------------------------------------------------------- /Chapter06/panic_unwinding.rs: -------------------------------------------------------------------------------- 1 | // panic_unwinding.rs 2 | 3 | use std::thread; 4 | 5 | fn alice() -> thread::JoinHandle<()> { 6 | thread::spawn(move || { 7 | bob(); 8 | }) 9 | } 10 | 11 | fn bob() { 12 | malice(); 13 | } 14 | 15 | fn malice() { 16 | panic!("malice is panicking!"); 17 | } 18 | 19 | fn main() { 20 | let child = alice(); 21 | let _ = child.join(); 22 | 23 | bob(); 24 | println!("This is unreachable code"); 25 | } 26 | -------------------------------------------------------------------------------- /Chapter08/async_channels.rs: -------------------------------------------------------------------------------- 1 | // async_channels.rs 2 | 3 | use std::thread; 4 | use std::sync::mpsc::channel; 5 | 6 | fn main() { 7 | let (tx, rx) = channel(); 8 | let join_handle = thread::spawn(move || { 9 | while let Ok(n) = rx.recv() { 10 | println!("Received {}", n); 11 | } 12 | }); 13 | 14 | for i in 0..10 { 15 | tx.send(i).unwrap(); 16 | } 17 | 18 | drop(tx); 19 | join_handle.join().unwrap(); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter05/result_basics_fixed.rs: -------------------------------------------------------------------------------- 1 | // result_basics_fixed.rs 2 | 3 | use std::fs::File; 4 | use std::io::Read; 5 | use std::path::Path; 6 | 7 | fn main() { 8 | let path = Path::new("data.txt"); 9 | let mut file = match File::open(&path) { 10 | Ok(file) => file, 11 | Err(err) => panic!("Error while opening file: {}", err), 12 | }; 13 | 14 | let mut s = String::new(); 15 | file.read_to_string(&mut s); 16 | println!("Message: {}", s); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter06/result_basics_fixed.rs: -------------------------------------------------------------------------------- 1 | // result_basics_fixed.rs 2 | 3 | use std::fs::File; 4 | use std::io::Read; 5 | use std::path::Path; 6 | 7 | fn main() { 8 | let path = Path::new("data.txt"); 9 | let mut file = match File::open(&path) { 10 | Ok(file) => file, 11 | Err(err) => panic!("Error while opening file: {}", err), 12 | }; 13 | 14 | let mut s = String::new(); 15 | file.read_to_string(&mut s); 16 | println!("Message: {}", s); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter02/myexponent/src/lib.rs: -------------------------------------------------------------------------------- 1 | // myexponent/src/lib.rs 2 | 3 | pub fn pow(base: i64, exponent: usize) -> i64 { 4 | let mut res = 1; 5 | if exponent == 0 { 6 | return 1; 7 | } 8 | for _ in 0..exponent { 9 | res *= base as i64; 10 | } 11 | res 12 | } 13 | 14 | #[cfg(test)] 15 | mod tests { 16 | use super::pow; 17 | #[test] 18 | fn minus_two_raised_three_is_minus_eight() { 19 | assert_eq!(pow(-2, 3), -8); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter05/refcell_basics.rs: -------------------------------------------------------------------------------- 1 | // refcell_basics.rs 2 | 3 | use std::cell::RefCell; 4 | 5 | #[derive(Debug)] 6 | struct Bag { 7 | item: Box 8 | } 9 | 10 | fn main() { 11 | let bag = RefCell::new(Bag { item: Box::new(1) }); 12 | let hand1 = &bag; 13 | let hand2 = &bag; 14 | *hand1.borrow_mut() = Bag { item: Box::new(2)}; 15 | *hand2.borrow_mut() = Bag { item: Box::new(3)}; 16 | println!("{:?} {:?}", hand1.borrow(), hand1.borrow_mut()); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter07/if_expr.rs: -------------------------------------------------------------------------------- 1 | // if_expr.rs 2 | 3 | fn compute(i: i32) -> i32 { 4 | 2 * i 5 | } 6 | 7 | fn main() { 8 | let result_msg = "done"; 9 | 10 | // if expression assignments 11 | let result = if result_msg == "done" { 12 | let some_work = compute(8); 13 | let stuff = compute(4); 14 | compute(2) + stuff // last expression gets assigned to result 15 | } else { 16 | compute(1) 17 | }; 18 | 19 | println!("{}", result); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter08/thread_arc.rs: -------------------------------------------------------------------------------- 1 | // thread_arc.rs 2 | 3 | use std::thread; 4 | use std::sync::Arc; 5 | 6 | fn main() { 7 | let nums = Arc::new(vec![0, 1, 2, 3, 4]); 8 | let mut childs = vec![]; 9 | for n in 0..5 { 10 | let ns = Arc::clone(&nums); 11 | let c = thread::spawn(move || { 12 | println!("{}", ns[n]); 13 | }); 14 | 15 | childs.push(c); 16 | } 17 | 18 | for c in childs { 19 | c.join().unwrap(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter10/native_counter/native/Cargo.toml: -------------------------------------------------------------------------------- 1 | # native_counter/native/Cargo.toml 2 | 3 | [package] 4 | name = "native_counter" 5 | version = "0.1.0" 6 | authors = ["Rahul Sharma "] 7 | license = "MIT" 8 | build = "build.rs" 9 | exclude = ["artifacts.json", "index.node"] 10 | edition = "2018" 11 | 12 | [lib] 13 | name = "native_counter" 14 | crate-type = ["dylib"] 15 | 16 | [build-dependencies] 17 | neon-build = "0.2.0" 18 | 19 | [dependencies] 20 | neon = "0.2.0" 21 | -------------------------------------------------------------------------------- /Chapter10/c_from_rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "c_from_rust" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 6 | ] 7 | 8 | [[package]] 9 | name = "cc" 10 | version = "1.0.25" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | 13 | [metadata] 14 | "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" 15 | -------------------------------------------------------------------------------- /Chapter05/lifetime_impls.rs: -------------------------------------------------------------------------------- 1 | // lifetime_impls.rs 2 | 3 | #[derive(Debug)] 4 | struct Number<'a> { 5 | num: &'a u8 6 | } 7 | 8 | impl<'a> Number<'a> { 9 | fn get_num(&self) -> &'a u8 { 10 | self.num 11 | } 12 | fn set_num(&mut self, new_number: &'a u8) { 13 | self.num = new_number 14 | } 15 | } 16 | 17 | fn main() { 18 | let a = 10; 19 | let mut num = Number { num: &a }; 20 | num.set_num(&23); 21 | println!("{:?}", num.get_num()); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter05/using_map.rs: -------------------------------------------------------------------------------- 1 | // using_map.rs 2 | 3 | fn get_nth(items: &Vec, nth: usize) -> Option { 4 | if nth < items.len() { 5 | Some(items[nth]) 6 | } else { 7 | None 8 | } 9 | } 10 | 11 | fn double(val: usize) -> usize { 12 | val * val 13 | } 14 | 15 | fn main() { 16 | let items = vec![7, 6, 4, 3, 5, 3, 10, 3, 2, 4]; 17 | println!("{}", items.len()); 18 | let doubled = get_nth(&items, 4).map(double); 19 | println!("{:?}", doubled); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter06/using_map.rs: -------------------------------------------------------------------------------- 1 | // using_map.rs 2 | 3 | fn get_nth(items: &Vec, nth: usize) -> Option { 4 | if nth < items.len() { 5 | Some(items[nth]) 6 | } else { 7 | None 8 | } 9 | } 10 | 11 | fn double(val: usize) -> usize { 12 | val * val 13 | } 14 | 15 | fn main() { 16 | let items = vec![7, 6, 4, 3, 5, 3, 10, 3, 2, 4]; 17 | println!("{}", items.len()); 18 | let doubled = get_nth(&items, 4).map(double); 19 | println!("{:?}", doubled); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter05/scopes.rs: -------------------------------------------------------------------------------- 1 | // scopes.rs 2 | 3 | fn main() { 4 | let level_0_str = String::from("foo"); 5 | { 6 | let level_1_number = 9; 7 | { 8 | let mut level_2_vector = vec![1, 2, 3]; 9 | level_2_vector.push(level_1_number); // can access 10 | } // level_2_vector goes out of scope here 11 | 12 | level_2_vector.push(4); // no longer exists 13 | } // level_1_number goes out of scope here 14 | } // level_0_str goes out of scope here 15 | -------------------------------------------------------------------------------- /Chapter03/bench_example/src/lib.rs: -------------------------------------------------------------------------------- 1 | // bench_example/src/lib.rs 2 | 3 | #![feature(test)] 4 | extern crate test; 5 | 6 | use test::Bencher; 7 | 8 | pub fn do_nothing_slowly() { 9 | print!("."); 10 | for _ in 1..10_000_000 {}; 11 | } 12 | 13 | pub fn do_nothing_fast() { 14 | } 15 | 16 | #[bench] 17 | fn bench_nothing_slowly(b: &mut Bencher) { 18 | b.iter(|| do_nothing_slowly()); 19 | } 20 | 21 | #[bench] 22 | fn bench_nothing_fast(b: &mut Bencher) { 23 | b.iter(|| do_nothing_fast()); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter03/doctest_demo/src/lib.rs: -------------------------------------------------------------------------------- 1 | // doctest_demo/src/lib.rs 2 | 3 | //! This crate provides functionality for adding things 4 | //! 5 | //! # Examples 6 | //! ``` 7 | //! use doctest_demo::sum; 8 | //! 9 | //! let work_a = 4; 10 | //! let work_b = 34; 11 | //! let total_work = sum(work_a, work_b); 12 | //! ``` 13 | 14 | /// Sum two arguments 15 | /// 16 | /// # Examples 17 | /// 18 | /// ``` 19 | /// assert_eq!(doctest_demo::sum(1, 1), 2); 20 | /// ``` 21 | pub fn sum(a: i8, b: i8) -> i8 { 22 | a + b 23 | } 24 | -------------------------------------------------------------------------------- /Chapter03/unit_test/src/lib.rs: -------------------------------------------------------------------------------- 1 | // unit_test/src/lib.rs 2 | 3 | // function we want to test 4 | fn sum(a: i8, b: i8) -> i8 { 5 | a + b 6 | } 7 | 8 | #[cfg(test)] 9 | mod tests { 10 | fn sum_inputs_outputs() -> Vec<((i8, i8), i8)> { 11 | vec![((1, 1), 2), ((0, 0), 0), ((2, -2), 0)] 12 | } 13 | 14 | #[test] 15 | fn test_sums() { 16 | for (input, output) in sum_inputs_outputs() { 17 | assert_eq!(crate::sum(input.0, input.1), output); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter03/criterion_demo/src/lib.rs: -------------------------------------------------------------------------------- 1 | // criterion_demo/src/lib.rs 2 | 3 | pub fn slow_fibonacci(nth: usize) -> u64 { 4 | if nth <= 1 { 5 | return nth as u64; 6 | } else { 7 | return slow_fibonacci(nth - 1) + slow_fibonacci(nth - 2); 8 | } 9 | } 10 | 11 | pub fn fast_fibonacci(nth: usize) -> u64 { 12 | let mut a = 0; 13 | let mut b = 1; 14 | let mut c = 0; 15 | for _ in 1..nth { 16 | c = a + b; 17 | a = b; 18 | b = c; 19 | } 20 | c 21 | } 22 | -------------------------------------------------------------------------------- /Chapter07/block_expr.rs: -------------------------------------------------------------------------------- 1 | // block_expr.rs 2 | 3 | fn main() { 4 | // using bare blocks to do multiple things at once 5 | let precompute = { 6 | let a = (-34i64).abs(); 7 | let b = 345i64.pow(3); 8 | let c = 3; 9 | a + b + c 10 | }; 11 | 12 | // match expressions 13 | let result_msg = match precompute { 14 | 42 => "done", 15 | a if a % 2 == 0 => "continue", 16 | _ => panic!("Oh no !") 17 | }; 18 | 19 | println!("{}", result_msg); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter05/result_common_pattern.rs: -------------------------------------------------------------------------------- 1 | // result_common_pattern.rs 2 | 3 | use std::string::FromUtf8Error; 4 | 5 | fn str_upper_match(str: Vec) -> Result { 6 | let ret = match String::from_utf8(str) { 7 | Ok(str) => str.to_uppercase(), 8 | Err(err) => return Err(err), 9 | }; 10 | 11 | println!("Conversion succeeded: {}", ret); 12 | Ok(ret) 13 | } 14 | 15 | fn main() { 16 | let invalid_str = str_upper_match(vec![197, 198]); 17 | println!("{:?}", invalid_str); 18 | } 19 | -------------------------------------------------------------------------------- /Chapter06/result_common_pattern.rs: -------------------------------------------------------------------------------- 1 | // result_common_pattern.rs 2 | 3 | use std::string::FromUtf8Error; 4 | 5 | fn str_upper_match(str: Vec) -> Result { 6 | let ret = match String::from_utf8(str) { 7 | Ok(str) => str.to_uppercase(), 8 | Err(err) => return Err(err), 9 | }; 10 | 11 | println!("Conversion succeeded: {}", ret); 12 | Ok(ret) 13 | } 14 | 15 | fn main() { 16 | let invalid_str = str_upper_match(vec![197, 198]); 17 | println!("{:?}", invalid_str); 18 | } 19 | -------------------------------------------------------------------------------- /Chapter04/trait_bound_functions.rs: -------------------------------------------------------------------------------- 1 | // trait_bounds_functions.rs 2 | 3 | use std::fmt::Debug; 4 | 5 | trait Eatable { 6 | fn eat(&self); 7 | } 8 | 9 | #[derive(Debug)] 10 | struct Food(T); 11 | 12 | #[derive(Debug)] 13 | struct Apple; 14 | 15 | impl Eatable for Food where T: Debug { 16 | fn eat(&self) { 17 | println!("Eating {:?}", self); 18 | } 19 | } 20 | 21 | fn eat(val: T) where T: Eatable { 22 | val.eat(); 23 | } 24 | 25 | fn main() { 26 | let apple = Food(Apple); 27 | eat(apple); 28 | } 29 | -------------------------------------------------------------------------------- /Chapter10/native_counter/native/src/lib.rs: -------------------------------------------------------------------------------- 1 | // native_counter/native/src/lib.rs 2 | 3 | #[macro_use] 4 | extern crate neon; 5 | 6 | use neon::prelude::*; 7 | 8 | fn count_words(mut cx: FunctionContext) -> JsResult { 9 | let text = cx.argument::(0)?.value(); 10 | let word = cx.argument::(1)?.value(); 11 | Ok(cx.number(text.split(" ").filter(|s| s == &word).count() as f64)) 12 | } 13 | 14 | register_module!(mut m, { 15 | m.export_function("count_words", count_words)?; 16 | Ok(()) 17 | }); 18 | -------------------------------------------------------------------------------- /Chapter01/vec.rs: -------------------------------------------------------------------------------- 1 | // vec.rs 2 | 3 | fn main() { 4 | let mut numbers_vec: Vec = Vec::new(); 5 | numbers_vec.push(1); 6 | numbers_vec.push(2); 7 | 8 | let mut vec_with_macro = vec![1]; 9 | vec_with_macro.push(2); 10 | let _ = vec_with_macro.pop(); // value ignored with `_` 11 | 12 | let message = if numbers_vec == vec_with_macro { 13 | "They are equal" 14 | } else { 15 | "Nah! They look different to me" 16 | }; 17 | 18 | println!("{} {:?} {:?}", message, numbers_vec, vec_with_macro); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/trait_constants.rs: -------------------------------------------------------------------------------- 1 | // trait_constants.rs 2 | 3 | trait Circular { 4 | const PI: f64 = 3.14; 5 | fn area(&self) -> f64; 6 | } 7 | 8 | struct Circle { 9 | rad: f64 10 | } 11 | 12 | impl Circular for Circle { 13 | fn area(&self) -> f64 { 14 | Circle::PI * self.rad * self.rad 15 | } 16 | } 17 | 18 | fn main() { 19 | let c_one = Circle { rad: 4.2 }; 20 | let c_two = Circle { rad: 75.2 }; 21 | println!("Area of circle one: {}", c_one.area()); 22 | println!("Area of circle two: {}", c_two.area()); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter08/arc_mutex.rs: -------------------------------------------------------------------------------- 1 | // arc_mutex.rs 2 | 3 | use std::sync::{Arc, Mutex}; 4 | use std::thread; 5 | 6 | fn main() { 7 | let vec = Arc::new(Mutex::new(vec![])); 8 | let mut childs = vec![]; 9 | for i in 0..5 { 10 | let mut v = vec.clone(); 11 | let t = thread::spawn(move || { 12 | let mut v = v.lock().unwrap(); 13 | v.push(i); 14 | }); 15 | childs.push(t); 16 | } 17 | 18 | for c in childs { 19 | c.join().unwrap(); 20 | } 21 | 22 | println!("{:?}", vec); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter10/rust_from_c/src/lib.rs: -------------------------------------------------------------------------------- 1 | // rust_from_c/src/lib.rs 2 | 3 | use std::ffi::CStr; 4 | use std::os::raw::c_char; 5 | 6 | #[repr(C)] 7 | pub enum Order { 8 | Gt, 9 | Lt, 10 | Eq 11 | } 12 | 13 | #[no_mangle] 14 | pub extern "C" fn compare_str(a: *const c_char, b: *const c_char) -> Order { 15 | let a = unsafe { CStr::from_ptr(a).to_bytes() }; 16 | let b = unsafe { CStr::from_ptr(b).to_bytes() }; 17 | if a > b { 18 | Order::Gt 19 | } else if a < b { 20 | Order::Lt 21 | } else { 22 | Order::Eq 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter01/hashmaps.rs: -------------------------------------------------------------------------------- 1 | // hashmaps.rs 2 | 3 | use std::collections::HashMap; 4 | 5 | fn main() { 6 | let mut fruits = HashMap::new(); 7 | fruits.insert("apple", 3); 8 | fruits.insert("mango", 6); 9 | fruits.insert("orange", 2); 10 | fruits.insert("avocado", 7); 11 | for (k, v) in &fruits { 12 | println!("I got {} {}", v, k); 13 | } 14 | 15 | fruits.remove("orange"); 16 | let old_avocado = fruits["avocado"]; 17 | fruits.insert("avocado", old_avocado + 5); 18 | println!("\nI now have {} avocados", fruits["avocado"]); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/destructure_struct.rs: -------------------------------------------------------------------------------- 1 | // destructure_struct.rs 2 | 3 | enum Food { 4 | Pizza, 5 | Salad 6 | } 7 | 8 | enum PaymentMode { 9 | Bitcoin, 10 | Credit 11 | } 12 | 13 | struct Order { 14 | count: u8, 15 | item: Food, 16 | payment: PaymentMode 17 | } 18 | 19 | fn main() { 20 | let food_order = Order { count: 2, 21 | item: Food::Salad, 22 | payment: PaymentMode::Credit }; 23 | 24 | // let can pattern match inner fields into new variables 25 | let Order { count, item, .. } = food_order; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter09/macro_map/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | #[macro_export] 3 | macro_rules! map { 4 | ( $( $k:expr => $v:expr ),* ) => ( 5 | { 6 | let mut map = ::std::collections::HashMap::new(); 7 | $( 8 | map.insert($k, $v); 9 | )* 10 | map 11 | } 12 | ); 13 | } 14 | 15 | #[cfg(test)] 16 | mod tests { 17 | #[test] 18 | fn test_map_macro() { 19 | let a = map! { 20 | "1" => 1, 21 | "2" => 2 22 | }; 23 | 24 | assert_eq!(a["1"], 1); 25 | assert_eq!(a["2"], 2); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter09/first_macro.rs: -------------------------------------------------------------------------------- 1 | // first_macro.rs 2 | 3 | use std::io::stdin; 4 | 5 | // A convenient macro to read input as string into a buffer 6 | macro_rules! scanline { 7 | ($x:expr) => ({ 8 | stdin().read_line(&mut $x).unwrap(); 9 | $x.trim(); 10 | }); 11 | () => ({ 12 | let mut s = String::new(); 13 | stdin().read_line(&mut s).unwrap(); 14 | s 15 | }); 16 | } 17 | 18 | fn main() { 19 | let mut input = String::new(); 20 | scanline!(input); 21 | println!("Hi {}",input); 22 | let a = scanline!(); 23 | println!("Hi {}", a); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter07/destructure_func_param.rs: -------------------------------------------------------------------------------- 1 | // destructure_func_param.rs 2 | 3 | struct Container { 4 | items_count: u32 5 | } 6 | 7 | fn increment_item(Container {mut items_count}: &mut Container) { 8 | items_count += 1; 9 | } 10 | 11 | fn calculate_cost(Container {items_count}: &Container) -> u32 { 12 | let rate = 67; 13 | rate * items_count 14 | } 15 | 16 | fn main() { 17 | let mut container = Container { 18 | items_count: 10 19 | }; 20 | 21 | increment_item(&mut container); 22 | let total_cost = calculate_cost(&container); 23 | println!("Total cost: {}", total_cost); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter07/serde_demo/src/main.rs: -------------------------------------------------------------------------------- 1 | 2 | use serde_derive::{Serialize, Deserialize}; 3 | 4 | #[derive(Debug, Serialize, Deserialize)] 5 | struct Foo { 6 | a: String, 7 | b: u64 8 | } 9 | 10 | impl Foo { 11 | fn new(a: &str, b: u64) -> Self { 12 | Self { 13 | a: a.to_string(), 14 | b 15 | } 16 | } 17 | } 18 | 19 | fn main() { 20 | let foo_json = serde_json::to_string(&Foo::new("It's that simple", 101)).unwrap(); 21 | println!("{:?}", foo_json); 22 | let foo_value: Foo = serde_json::from_str(&foo_json).unwrap(); 23 | println!("{:?}", foo_value); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter08/threads_sharing.rs: -------------------------------------------------------------------------------- 1 | 2 | // shared_owner_threads.rs 3 | 4 | use std::thread; 5 | use std::rc::Rc; 6 | use std::sync::Mutex; 7 | 8 | struct Payload { 9 | data: Mutex 10 | } 11 | 12 | impl Payload { 13 | fn new(val: u32) -> Self { 14 | Payload { 15 | data: Mutex::new(val) 16 | } 17 | } 18 | 19 | fn inc(&mut self) { 20 | *self.data.lock().unwrap() += 1; 21 | } 22 | } 23 | 24 | fn main() { 25 | let a = Rc::new(Payload::new(0)); 26 | thread::spawn(|| { 27 | loop { 28 | let b = a.clone(); 29 | } 30 | }); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Chapter04/super_player/src/main.rs: -------------------------------------------------------------------------------- 1 | // super_player/src/main.rs 2 | 3 | mod media; 4 | 5 | struct Audio(String); 6 | struct Video(String); 7 | 8 | impl Playable for Audio { 9 | fn play(&self) { 10 | println!("🎵 Now playing: {}", self.0); 11 | } 12 | } 13 | 14 | impl Playable for Video { 15 | fn play(&self) { 16 | println!("🎵 Now playing: {}", self.0); 17 | } 18 | } 19 | 20 | fn main() { 21 | println!("Super player!"); 22 | let audio = Audio("ambient_music.mp3".to_string()); 23 | let video = Video("big_buck_bunny.mkv".to_string()); 24 | audio.play(); 25 | video.play(); 26 | } 27 | -------------------------------------------------------------------------------- /Chapter04/trait_bound_intro_fixed.rs: -------------------------------------------------------------------------------- 1 | // trait_bounds_intro.rs 2 | 3 | struct Game; 4 | struct Enemy; 5 | struct Hero; 6 | 7 | trait Loadable { 8 | fn init(&self); 9 | } 10 | 11 | impl Loadable for Enemy { 12 | fn init(&self) { 13 | println!("Enemy loaded"); 14 | } 15 | } 16 | 17 | impl Loadable for Hero { 18 | fn init(&self) { 19 | println!("Hero loaded"); 20 | } 21 | } 22 | 23 | impl Game { 24 | fn load(&self, entity: T) { 25 | entity.init(); 26 | } 27 | } 28 | 29 | fn main() { 30 | let game = Game; 31 | game.load(Enemy); 32 | game.load(Hero); 33 | } 34 | -------------------------------------------------------------------------------- /Chapter10/edit_distance/src/lib.rs: -------------------------------------------------------------------------------- 1 | // edit_distance/src/lib.rs 2 | 3 | mod bindings; 4 | 5 | use crate::bindings::levenshtein; 6 | use std::ffi::CString; 7 | 8 | pub fn levenshtein_safe(a: &str, b: &str) -> u32 { 9 | let a = CString::new(a).unwrap(); 10 | let b = CString::new(b).unwrap(); 11 | let distance = unsafe { levenshtein(a.as_ptr(), b.as_ptr()) }; 12 | distance 13 | } 14 | 15 | #[cfg(test)] 16 | mod tests { 17 | use levenshtein_safe; 18 | #[test] 19 | fn test_levenshtein_safe_wrapper() { 20 | let a = "foo"; 21 | let b = "fooo"; 22 | assert_eq!(1,levenshtein_safe(a, b)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter11/user_auth/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate log; 3 | 4 | pub struct User { 5 | name: String, 6 | pass: String, 7 | } 8 | 9 | impl User { 10 | pub fn new(name: &str, pass: &str) -> Self { 11 | User { 12 | name: name.to_string(), 13 | pass: pass.to_string(), 14 | } 15 | } 16 | 17 | pub fn sign_in(&self, pass: &str) { 18 | debug!("Attempting sign in !"); 19 | if pass != self.pass { 20 | info!("Signing in user: {}", self.name); 21 | } else { 22 | error!("Login failed for user: {}", self.name); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chapter04/trait_objects.rs: -------------------------------------------------------------------------------- 1 | // trait_objects.rs 2 | 3 | use std::fmt::Debug; 4 | 5 | #[derive(Debug)] 6 | struct Square(f32); 7 | #[derive(Debug)] 8 | struct Rectangle(f32, f32); 9 | 10 | trait Area: Debug { 11 | fn get_area(&self) -> f32; 12 | } 13 | 14 | impl Area for Square { 15 | fn get_area(&self) -> f32 { 16 | self.0 * self.0 17 | } 18 | } 19 | 20 | impl Area for Rectangle { 21 | fn get_area(&self) -> f32 { 22 | self.0 * self.1 23 | } 24 | } 25 | 26 | fn main() { 27 | let shapes: Vec<&dyn Area> = vec![&Square(3f32), &Rectangle(4f32, 2f32)]; 28 | for s in shapes { 29 | println!("{:?}", s); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chapter10/word_suffix/README.md: -------------------------------------------------------------------------------- 1 | 2 | You need a virtual python environment to run the example in this directory. 3 | 4 | To install pip and virtualenv run: 5 | 6 | ```bash 7 | sudo apt-get install python3-pip 8 | sudo pip3 install virtualenv 9 | ``` 10 | 11 | Then, create virtual by running: 12 | ``` 13 | virtualenv -p /usr/bin/python3.5 test_word_suffix 14 | ``` 15 | 16 | and activate the environment by running 17 | ``` 18 | source test_word_suffix/bin/activate 19 | ``` 20 | 21 | You should see your prompt change with `(test_word_suffix)` prefix. 22 | 23 | After that, Run the example main.py by invoking `python main.py` 24 | 25 | To deactivate the virtual environment, run `deactivate`. -------------------------------------------------------------------------------- /Chapter08/sync_channels.rs: -------------------------------------------------------------------------------- 1 | // sync_channels.rs 2 | 3 | use std::thread; 4 | use std::sync::mpsc; 5 | 6 | fn main() { 7 | let (tx, rx) = mpsc::sync_channel(1); 8 | let tx_clone = tx.clone(); 9 | 10 | let _ = tx.send(0); 11 | 12 | thread::spawn(move || { 13 | let _ = tx.send(1); 14 | }); 15 | 16 | thread::spawn(move || { 17 | let _ = tx_clone.send(2); 18 | }); 19 | 20 | println!("Received {} via the channel", rx.recv().unwrap()); 21 | println!("Received {} via the channel", rx.recv().unwrap()); 22 | println!("Received {} via the channel", rx.recv().unwrap()); 23 | println!("Received {:?} via the channel", rx.recv()); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter04/trait_composition.rs: -------------------------------------------------------------------------------- 1 | // traits_composition.rs 2 | 3 | trait Eat { 4 | fn eat(&self) { 5 | println!("eat"); 6 | } 7 | } 8 | trait Code { 9 | fn code(&self) { 10 | println!("code"); 11 | } 12 | } 13 | trait Sleep { 14 | fn sleep(&self) { 15 | println!("sleep"); 16 | } 17 | } 18 | 19 | trait Programmer : Eat + Code + Sleep { 20 | fn animate(&self) { 21 | self.eat(); 22 | self.code(); 23 | self.sleep(); 24 | println!("repeat!"); 25 | } 26 | } 27 | 28 | struct Bob; 29 | impl Programmer for Bob {} 30 | impl Eat for Bob {} 31 | impl Code for Bob {} 32 | impl Sleep for Bob {} 33 | 34 | fn main() { 35 | Bob.animate(); 36 | } 37 | -------------------------------------------------------------------------------- /Chapter01/tuple_struct.rs: -------------------------------------------------------------------------------- 1 | // tuple_struct.rs 2 | 3 | struct Color(u8, u8, u8); 4 | 5 | fn main() { 6 | let white = Color(255, 255, 255); 7 | 8 | // You can pull them out by index 9 | let red = white.0; 10 | let green = white.1; 11 | let blue = white.2; 12 | 13 | println!("Red value: {}", red); 14 | println!("Green value: {}", green); 15 | println!("Blue value: {}\n", blue); 16 | 17 | let orange = Color(255, 165, 0); 18 | 19 | // You can also destructure the fields directly 20 | let Color(r, g, b) = orange; 21 | println!("R: {}, G: {}, B: {} (orange)", r, g, b); 22 | 23 | // Can also ignore fields while destructuring 24 | let Color(r, _, b) = orange; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter10/edit_distance/build.rs: -------------------------------------------------------------------------------- 1 | // edit_distance/build.rs 2 | 3 | use std::path::PathBuf; 4 | 5 | fn main() { 6 | println!("cargo:rustc-rerun-if-changed=."); 7 | println!("cargo:rustc-link-search=."); 8 | println!("cargo:rustc-link-lib=levenshtein"); 9 | 10 | cc::Build::new() 11 | .file("lib/levenshtein.c") 12 | .out_dir(".") 13 | .compile("levenshtein"); 14 | 15 | let bindings = bindgen::Builder::default() 16 | .header("lib/levenshtein.h") 17 | .generate() 18 | .expect("Unable to generate bindings"); 19 | 20 | let out_path = PathBuf::from("./src/"); 21 | bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings!"); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter01/structs.rs: -------------------------------------------------------------------------------- 1 | // structs.rs 2 | 3 | struct Player { 4 | name: String, 5 | iq: u8, 6 | friends: u8, 7 | score: u16 8 | } 9 | 10 | fn bump_player_score(mut player: Player, score: u16) { 11 | player.score += 120; 12 | println!("Updated player stats:"); 13 | println!("Name: {}", player.name); 14 | println!("IQ: {}", player.iq); 15 | println!("Friends: {}", player.friends); 16 | println!("Score: {}", player.score); 17 | } 18 | 19 | fn main() { 20 | let name = "Alice".to_string(); 21 | let player = Player { name, 22 | iq: 171, 23 | friends: 134, 24 | score: 1129 }; 25 | 26 | bump_player_score(player, 120); 27 | } 28 | -------------------------------------------------------------------------------- /Chapter03/logic_gates/tests/half_adder.rs: -------------------------------------------------------------------------------- 1 | // logic_gates/tests/half_adder.rs 2 | 3 | use logic_gates::{and, xor}; 4 | 5 | pub type Sum = u8; 6 | pub type Carry = u8; 7 | 8 | pub fn half_adder_input_output() -> Vec<((u8, u8), (Sum, Carry))> { 9 | vec![ 10 | ((0, 0), (0, 0)), 11 | ((0, 1), (1, 0)), 12 | ((1, 0), (1, 0)), 13 | ((1, 1), (0, 1)), 14 | ] 15 | } 16 | 17 | /// This function implements a half adder using primitive gates 18 | fn half_adder(a: u8, b: u8) -> (Sum, Carry) { 19 | (xor(a, b), and(a, b)) 20 | } 21 | 22 | #[test] 23 | fn one_bit_adder() { 24 | for (inn, out) in half_adder_input_output() { 25 | let (a, b) = inn; 26 | assert_eq!(half_adder(a, b), out); 27 | } 28 | } -------------------------------------------------------------------------------- /Chapter07/let_ref_mut.rs: -------------------------------------------------------------------------------- 1 | // let_ref_mut.rs 2 | 3 | #[derive(Debug)] 4 | struct Items(u32); 5 | 6 | fn main() { 7 | let items = Items(2); 8 | let items_ptr = &items; 9 | let ref items_ref = items; 10 | 11 | assert_eq!(items_ptr as *const Items, items_ref as *const Items); 12 | 13 | let mut a = Items(20); 14 | // using scope to limit the mutation of `a` within this block by b 15 | { 16 | // can take a mutable reference like this too 17 | let ref mut b = a; // same as: let b = &mut a; 18 | b.0 += 25; 19 | } 20 | 21 | println!("{:?}", items); 22 | 23 | println!("{:?}", a); // without the above scope 24 | // this does not compile. Try removing the scope 25 | } 26 | -------------------------------------------------------------------------------- /Chapter13/hyperurl/src/main.rs: -------------------------------------------------------------------------------- 1 | // hyperurl/src/main.rs 2 | 3 | use log::{info, error}; 4 | use std::env; 5 | use hyper::Server; 6 | use hyper::service::service_fn; 7 | use hyper::rt::{self, Future}; 8 | 9 | mod shortener; 10 | mod service; 11 | mod index; 12 | 13 | use crate::service::url_service; 14 | 15 | const LISTEN_ADDR: &str = "127.0.0.1:3002"; 16 | 17 | fn main() { 18 | env::set_var("RUST_LOG","hyperurl=info"); 19 | pretty_env_logger::init(); 20 | let addr = LISTEN_ADDR.parse().unwrap(); 21 | 22 | let server = Server::bind(&addr) 23 | .serve(|| service_fn(url_service)) 24 | .map_err(|e| error!("server error: {}", e)); 25 | info!("hyperurl is listening at {}", addr); 26 | 27 | rt::run(server); 28 | } 29 | -------------------------------------------------------------------------------- /Chapter07/enum_struct_consts.rs: -------------------------------------------------------------------------------- 1 | // enum_struct_consts.rs 2 | 3 | use std::collections::HashMap; 4 | 5 | #[derive(Debug)] 6 | struct Inventory { 7 | inner: HashMap 8 | } 9 | 10 | impl Inventory { 11 | const DEFAULT_COUNT: u32 = 20; 12 | } 13 | 14 | fn put_into_inventory(inventory: &mut Inventory, item: String, count: Option) { 15 | if let Some(c) = count { 16 | inventory.inner.insert(item, c); 17 | } else { 18 | inventory.inner.insert(item, Inventory::DEFAULT_COUNT); 19 | } 20 | } 21 | 22 | fn main() { 23 | let food = "Apple".to_string(); 24 | let mut inventory = Inventory { inner: HashMap::new() }; 25 | put_into_inventory(&mut inventory, food, None); 26 | println!("{:?}", inventory); 27 | } 28 | -------------------------------------------------------------------------------- /Chapter04/trait_inheritance.rs: -------------------------------------------------------------------------------- 1 | // trait_inheritance.rs 2 | 3 | trait Vehicle { 4 | fn get_price(&self) -> u64; 5 | } 6 | 7 | trait Car: Vehicle { 8 | fn model(&self) -> String; 9 | } 10 | 11 | struct TeslaRoadster { 12 | model: String, 13 | release_date: u16 14 | } 15 | 16 | impl TeslaRoadster { 17 | fn new(model: &str, release_date: u16) -> Self { 18 | Self { model: model.to_string(), release_date } 19 | } 20 | } 21 | 22 | impl Car for TeslaRoadster { 23 | fn model(&self) -> String { 24 | "Tesla Roadster I".to_string() 25 | } 26 | } 27 | 28 | fn main() { 29 | let my_roadster = TeslaRoadster::new("Tesla Roadster II", 2020); 30 | println!("{} is priced at ${}", my_roadster.model, my_roadster.get_price()); 31 | } 32 | -------------------------------------------------------------------------------- /Chapter07/pointer_layouts.rs: -------------------------------------------------------------------------------- 1 | // pointer_layouts.rs 2 | 3 | trait Position {} 4 | 5 | struct Coordinates(f64, f64); 6 | 7 | impl Position for Coordinates {} 8 | 9 | fn main() { 10 | let val = Coordinates(1.0, 2.0); 11 | let ref_: &Coordinates = &val; 12 | let pos_ref: &Position = &val as &Position; 13 | let ptr: *const Coordinates = &val as *const Coordinates; 14 | let pos_ptr: *const Position = &val as *const Position; 15 | 16 | println!("ref_: {}", std::mem::size_of_val(&ref_)); 17 | println!("ptr: {}", std::mem::size_of_val(&ptr)); 18 | println!("val: {}", std::mem::size_of_val(&val)); 19 | println!("pos_ref: {}", std::mem::size_of_val(&pos_ref)); 20 | println!("pos_ptr: {}", std::mem::size_of_val(&pos_ptr)); 21 | } 22 | -------------------------------------------------------------------------------- /Chapter01/loop_labels.rs: -------------------------------------------------------------------------------- 1 | // loop_labels.rs 2 | 3 | fn silly_sub(a: i32, b: i32) -> i32 { 4 | let mut result = 0; 5 | 'increment: loop { 6 | if result == a { 7 | let mut dec = b; 8 | 'decrement: loop { 9 | if dec == 0 { 10 | // breaks directly out of 'increment loop 11 | break 'increment; 12 | } else { 13 | result -= 1; 14 | dec -= 1; 15 | } 16 | } 17 | } else { 18 | result += 1; 19 | } 20 | } 21 | result 22 | } 23 | 24 | fn main() { 25 | let a = 10; 26 | let b = 4; 27 | let result = silly_sub(a, b); 28 | println!("{} minus {} is {}", a, b, result); 29 | } 30 | -------------------------------------------------------------------------------- /Chapter10/c_from_rust/src/main.rs: -------------------------------------------------------------------------------- 1 | // c_from_rust/src/main.rs 2 | 3 | use std::os::raw::{c_char, c_uint}; 4 | 5 | use std::ffi::CString; 6 | 7 | extern "C" { 8 | fn mystrlen(str: *const c_char) -> c_uint; 9 | } 10 | 11 | fn safe_mystrlen(str: &str) -> Option { 12 | let c_string = match CString::new(str) { 13 | Ok(c) => c, 14 | Err(_) => return None 15 | }; 16 | 17 | unsafe { 18 | Some(mystrlen(c_string.as_ptr())) 19 | } 20 | } 21 | 22 | fn main() { 23 | let c_string = CString::new("C From Rust").expect("failed"); 24 | let count = unsafe { 25 | mystrlen(c_string.as_ptr()) 26 | }; 27 | println!("c_string's length is {}", count); 28 | println!("c_string's length is {:?}", safe_mystrlen("C From Rust")); 29 | } 30 | -------------------------------------------------------------------------------- /Chapter11/slog_demo/src/weapon.rs: -------------------------------------------------------------------------------- 1 | // slog_demo/weapon.rs 2 | 3 | use slog::Logger; 4 | use std::fmt; 5 | 6 | #[derive(Debug)] 7 | pub struct PlasmaCannon(pub Logger); 8 | 9 | impl PlasmaCannon { 10 | pub fn fire(&self) { 11 | info!(self.0, "Pew Pew !!"); 12 | } 13 | } 14 | 15 | #[derive(Debug)] 16 | pub struct RailGun(pub Logger); 17 | 18 | impl RailGun { 19 | pub fn fire(&self) { 20 | info!(self.0, "Swoosh !!"); 21 | } 22 | } 23 | 24 | impl fmt::Display for PlasmaCannon { 25 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 26 | write!(f, stringify!(PlasmaCannon)) 27 | } 28 | } 29 | 30 | impl fmt::Display for RailGun { 31 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 32 | write!(f, stringify!(RailGun)) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chapter12/rudis_sync/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "lazy_static" 3 | version = "1.2.0" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | 6 | [[package]] 7 | name = "resp" 8 | version = "1.0.2" 9 | source = "git+https://github.com/creativcoder/resp#b415e0bf0347a2669b774d48fab68728559f4b10" 10 | 11 | [[package]] 12 | name = "rudis_sync" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "resp 1.0.2 (git+https://github.com/creativcoder/resp)", 17 | ] 18 | 19 | [metadata] 20 | "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" 21 | "checksum resp 1.0.2 (git+https://github.com/creativcoder/resp)" = "" 22 | -------------------------------------------------------------------------------- /Chapter01/struct_methods.rs: -------------------------------------------------------------------------------- 1 | // struct_methods.rs 2 | 3 | struct Player { 4 | name: String, 5 | iq: u8, 6 | friends: u8 7 | } 8 | 9 | impl Player { 10 | fn with_name(name: &str) -> Player { 11 | Player { 12 | name: name.to_string(), 13 | iq: 100, 14 | friends: 100 15 | } 16 | } 17 | 18 | fn get_friends(&self) -> u8 { 19 | self.friends 20 | } 21 | 22 | fn set_friends(&mut self, count: u8) { 23 | self.friends = count; 24 | } 25 | } 26 | 27 | fn main() { 28 | let mut player = Player::with_name("Dave"); 29 | player.set_friends(23); 30 | println!("{}'s friends count: {}", player.name, player.get_friends()); 31 | // another way to call instance methods. 32 | let _ = Player::get_friends(&player); 33 | } 34 | -------------------------------------------------------------------------------- /Chapter11/slog_demo/src/enemy.rs: -------------------------------------------------------------------------------- 1 | // slog_demo/enemy.rs 2 | 3 | use weapon::RailGun; 4 | use PlayingCharacter; 5 | use slog::Logger; 6 | 7 | pub struct Enemy { 8 | name: String, 9 | logger: Logger, 10 | weapon: RailGun 11 | } 12 | 13 | impl Enemy { 14 | pub fn new(logger: &Logger, name: &str) -> Self { 15 | let enemy_log = logger.new(o!("Enemy" => format!("{}", name))); 16 | let weapon_log = enemy_log.new(o!("RailGun" => "S12")); 17 | Self { 18 | name: name.to_string(), 19 | logger: enemy_log, 20 | weapon: RailGun(weapon_log) 21 | } 22 | } 23 | } 24 | 25 | impl PlayingCharacter for Enemy { 26 | fn shoot(&self) { 27 | warn!(self.logger, "Enemy shooting with {}", self.weapon); 28 | self.weapon.fire(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter13/shorten/src/main.rs: -------------------------------------------------------------------------------- 1 | // shorten/src/main.rs 2 | 3 | use quicli::prelude::*; 4 | use structopt::StructOpt; 5 | use reqwest::Client; 6 | 7 | const HYPERURL_ADDR: &str = "127.0.0.1:3002"; 8 | const HTTP_PREFIX: &str = "http://"; 9 | 10 | #[derive(Debug, StructOpt)] 11 | struct Cli { 12 | #[structopt(long = "url", short = "u")] 13 | url: String, 14 | #[structopt(flatten)] 15 | verbosity: Verbosity, 16 | } 17 | 18 | fn main() -> CliResult { 19 | let args = Cli::from_args(); 20 | println!("Shortening: {}", args.url); 21 | let client = Client::new(); 22 | let mut res = client 23 | .post(&format!("{}{}/shorten", HTTP_PREFIX, HYPERURL_ADDR)) 24 | .body(args.url) 25 | .send()?; 26 | let a: String = res.text().unwrap(); 27 | println!("{}{}", HTTP_PREFIX, a); 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /Chapter11/slog_demo/src/player.rs: -------------------------------------------------------------------------------- 1 | // slog_demo/player.rs 2 | 3 | use slog::Logger; 4 | 5 | use weapon::PlasmaCannon; 6 | use PlayingCharacter; 7 | 8 | pub struct Player { 9 | name: String, 10 | logger: Logger, 11 | weapon: PlasmaCannon 12 | } 13 | 14 | impl Player { 15 | pub fn new(logger: &Logger, name: &str) -> Self { 16 | let player_log = logger.new(o!("Player" => format!("{}", name))); 17 | let weapon_log = player_log.new(o!("PlasmaCannon" => "M435")); 18 | Self { 19 | name: name.to_string(), 20 | logger: player_log, 21 | weapon: PlasmaCannon(weapon_log), 22 | } 23 | } 24 | } 25 | 26 | impl PlayingCharacter for Player { 27 | fn shoot(&self) { 28 | info!(self.logger, "Player shooting with {}", self.weapon); 29 | self.weapon.fire(); 30 | } 31 | } -------------------------------------------------------------------------------- /Chapter04/expressions.rs: -------------------------------------------------------------------------------- 1 | // expressions.rs 2 | 3 | fn compute() -> i32 { 4 | 234 5 | } 6 | 7 | fn main() { 8 | // using bare blocks to do multiple things at once 9 | let precompute = { 10 | let a = (-34i64).abs(); 11 | let (b, _) = 345i64.overflowing_rem(34); 12 | let c = 3; 13 | a + b + c 14 | }; 15 | 16 | // match expressions 17 | let result_msg = match precompute { 18 | 42 => "done", 19 | a if a % 2 == 0 => "continue", 20 | _ => panic!("Oh no !") 21 | }; 22 | 23 | // if expressions 24 | let result = if result_msg == "done" { 25 | let some_work = compute(); 26 | let stuff = compute(); 27 | compute() + stuff // last expression gets assigned to result 28 | } else { 29 | compute() 30 | }; 31 | 32 | println!("{}", result); 33 | } 34 | -------------------------------------------------------------------------------- /Chapter11/user_auth/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "cfg-if" 3 | version = "0.1.6" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | 6 | [[package]] 7 | name = "log" 8 | version = "0.4.6" 9 | source = "registry+https://github.com/rust-lang/crates.io-index" 10 | dependencies = [ 11 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 12 | ] 13 | 14 | [[package]] 15 | name = "user_auth" 16 | version = "0.1.0" 17 | dependencies = [ 18 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 19 | ] 20 | 21 | [metadata] 22 | "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" 23 | "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" 24 | -------------------------------------------------------------------------------- /Chapter05/cell_cache.rs: -------------------------------------------------------------------------------- 1 | // cell_cache.rs 2 | 3 | use std::cell::Cell; 4 | 5 | struct Point { 6 | x: u8, 7 | y: u8, 8 | cached_sum: Cell> 9 | } 10 | 11 | impl Point { 12 | fn sum(&self) -> u8 { 13 | match self.cached_sum.get() { 14 | Some(sum) => { 15 | println!("Got from cache: {}", sum); 16 | sum 17 | }, 18 | None => { 19 | let new_sum = self.x + self.y; 20 | self.cached_sum.set(Some(new_sum)); 21 | println!("Set cache: {}", new_sum); 22 | new_sum 23 | } 24 | } 25 | } 26 | } 27 | 28 | fn main() { 29 | let p = Point { x: 8, y: 9, cached_sum: Cell::new(None) }; 30 | println!("Summed result: {}", p.sum()); 31 | println!("Summed result: {}", p.sum()); 32 | } 33 | -------------------------------------------------------------------------------- /Chapter01/enums.rs: -------------------------------------------------------------------------------- 1 | // enums.rs 2 | 3 | #[derive(Debug)] 4 | enum Direction { 5 | N, 6 | E, 7 | S, 8 | W 9 | } 10 | 11 | enum PlayerAction { 12 | Move { 13 | direction: Direction, 14 | speed: u8 15 | }, 16 | Wait, 17 | Attack(Direction) 18 | } 19 | 20 | fn main() { 21 | let simulated_player_action = PlayerAction::Move { 22 | direction: Direction::N, 23 | speed: 2, 24 | }; 25 | match simulated_player_action { 26 | PlayerAction::Wait => println!("Player wants to wait"), 27 | PlayerAction::Move { direction, speed } => { 28 | println!("Player wants to move in direction {:?} with speed {}", 29 | direction, speed) 30 | } 31 | PlayerAction::Attack(direction) => { 32 | println!("Player wants to attack direction {:?}", direction) 33 | } 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter05/linked_list.rs: -------------------------------------------------------------------------------- 1 | // rc.rs 2 | 3 | use std::rc::Rc; 4 | 5 | #[derive(Debug)] 6 | struct LinkedList { 7 | head: Option>> 8 | } 9 | 10 | #[derive(Debug)] 11 | struct Node { 12 | next: Option>>, 13 | data: T 14 | } 15 | 16 | impl LinkedList { 17 | fn new() -> Self { 18 | LinkedList { head: None } 19 | } 20 | 21 | fn append(&self, data: T) -> Self { 22 | LinkedList { 23 | head: Some(Rc::new(Node { 24 | data: data, 25 | next: self.head.clone() 26 | })) 27 | } 28 | } 29 | } 30 | 31 | fn main() { 32 | let list_of_nums = LinkedList::new().append(1).append(2); 33 | println!("nums: {:?}", list_of_nums); 34 | 35 | let list_of_strs = LinkedList::new().append("foo").append("bar"); 36 | println!("strs: {:?}", list_of_strs); 37 | } 38 | -------------------------------------------------------------------------------- /Chapter02/cargo_manifest_example/Cargo.toml: -------------------------------------------------------------------------------- 1 | # cargo_manifest_example/Cargo.toml 2 | # We can write comments with `#` within a manifest file 3 | 4 | [package] 5 | name = "cargo-metadata-example" 6 | version = "1.2.3" 7 | description = "An example of Cargo metadata" 8 | documentation = "https://docs.rs/dummy_crate" 9 | license = "MIT" 10 | readme = "README.md" 11 | keywords = ["example", "cargo", "mastering"] 12 | authors = ["Jack Daniels ", "Iddie Ezzard "] 13 | build = "build.rs" 14 | edition = "2018" 15 | 16 | [package.metadata.settings] 17 | default-data-path = "/var/lib/example" 18 | 19 | [features] 20 | default=["mysql"] 21 | 22 | [build-dependencies] 23 | syntex = "^0.58" 24 | 25 | [dependencies] 26 | serde = "1.0" 27 | serde_json = "1.0" 28 | time = { git = "https://github.com/rust-lang/time", branch = "master" } 29 | mysql = { version = "1.2", optional = true } 30 | sqlite = { version = "2.5", optional = true } 31 | -------------------------------------------------------------------------------- /Chapter10/word_suffix/src/lib.rs: -------------------------------------------------------------------------------- 1 | // word_suffix/src/lib.rs 2 | 3 | //! A demo python module in Rust that can extract words 4 | //! from a comma seperated string of words that ends with the given suffix 5 | 6 | #[macro_use] 7 | extern crate pyo3; 8 | use pyo3::prelude::*; 9 | 10 | /// This module is a python module implemented in Rust. 11 | #[pymodinit] 12 | fn word_suffix(_py: Python, m: &PyModule) -> PyResult<()> { 13 | m.add_function(wrap_function!(find_words))?; 14 | Ok(()) 15 | } 16 | 17 | #[pyfunction] 18 | fn find_words(src: &str, suffix: &str) -> PyResult> { 19 | let mut v = vec![]; 20 | let filtered = src.split(",").filter_map(|s| { 21 | let trimmed = s.trim(); 22 | if trimmed.ends_with(&suffix) { 23 | Some(trimmed.to_owned()) 24 | } else { 25 | None 26 | } 27 | }); 28 | for s in filtered { 29 | v.push(s); 30 | } 31 | Ok(v) 32 | } 33 | -------------------------------------------------------------------------------- /Chapter01/enum_methods.rs: -------------------------------------------------------------------------------- 1 | 2 | enum PaymentMode { 3 | Debit, 4 | Credit, 5 | Paypal 6 | } 7 | 8 | // Bunch of dummy payment handlers 9 | 10 | fn pay_by_credit(amt: u64) { 11 | println!("Processing credit payment of {}", amt); 12 | } 13 | fn pay_by_debit(amt: u64) { 14 | println!("Processing debit payment of {}", amt); 15 | } 16 | fn paypal_redirect(amt: u64) { 17 | println!("Redirecting to paypal for amount: {}", amt); 18 | } 19 | 20 | impl PaymentMode { 21 | fn pay(&self, amount: u64) { 22 | match self { 23 | PaymentMode::Debit => pay_by_debit(amount), 24 | PaymentMode::Credit => pay_by_credit(amount), 25 | PaymentMode::Paypal => paypal_redirect(amount) 26 | } 27 | } 28 | } 29 | 30 | fn get_saved_payment_mode() -> PaymentMode { 31 | PaymentMode::Debit 32 | } 33 | 34 | fn main() { 35 | let payment_mode = get_saved_payment_mode(); 36 | payment_mode.pay(512); 37 | } 38 | -------------------------------------------------------------------------------- /Chapter09/http_tester/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | #[macro_export] 3 | macro_rules! http_test { 4 | ($url:tt GET => $code:expr) => { 5 | let request = reqwest::get($url).unwrap(); 6 | println!("Testing GET {} => {}", $url, $code); 7 | assert_eq!(request.status().as_u16(), $code); 8 | }; 9 | ($url:tt POST => $code:expr, $($k:expr => $v:expr),*) => { 10 | let params = [$(($k, $v),)*]; 11 | let client = reqwest::Client::new(); 12 | let res = client.post($url) 13 | .form(¶ms) 14 | .send().unwrap(); 15 | println!("Testing POST {} => {}", $url, $code); 16 | assert_eq!(res.status().as_u16(), $code); 17 | }; 18 | } 19 | 20 | #[cfg(test)] 21 | mod tests { 22 | #[test] 23 | fn test_http_verbs() { 24 | http_test!("http://duckduckgo.com" GET => 200); 25 | http_test!("http://httpbin.org/post" POST => 200, "hello" => "world", "foo" => "bar"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter07/string_apis.rs: -------------------------------------------------------------------------------- 1 | // string_apis.rs 2 | 3 | fn main() { 4 | let mut empty_string = String::new(); 5 | let empty_string_with_capacity = String::with_capacity(50); 6 | let string_from_bytestring: String = String::from_utf8(vec![82, 85, 83, 7 | 84]).expect("Creating String from bytestring failed"); 8 | 9 | println!("Length of the empty string is {}", empty_string.len()); 10 | println!("Length of the empty string with capacity is {}", 11 | empty_string_with_capacity.len()); 12 | println!("Length of the string from a bytestring is {}", 13 | string_from_bytestring.len()); 14 | 15 | println!("Bytestring says {}", string_from_bytestring); 16 | 17 | empty_string.push('1'); 18 | println!("1) Empty string now contains {}", empty_string); 19 | empty_string.push_str("2345"); 20 | println!("2) Empty string now contains {}", empty_string); 21 | println!("Length of the previously empty string is now {}", 22 | empty_string.len()); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter13/hyperurl/src/index.rs: -------------------------------------------------------------------------------- 1 | // hyperurl/src/index.rs 2 | 3 | pub static INDEX_PAGE: &str = r##" 4 | 5 | 6 | 7 | 8 | 9 | 10 | hyperurl - A url shortener in Rust 11 | 12 | 13 | 14 |

hyperurl - A url shortening service

15 |

To shorten a url, make a post request using curl as:

16 |

curl --data "https://creativcoder.github.io" http://localhost:3002/shorten

17 |

You will get a reply as:

18 |

{ 19 | "127.0.0.1:3002/992a7": "https://creativcoder.github.io" 20 | }

21 |

Put the shortened url (127.0.0.1:3002/992a7) in the browser to get redirected to the original website.

22 |

Made with ❤ with hyper in Rust

23 | 24 | 25 | "##; 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 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 | -------------------------------------------------------------------------------- /Chapter13/linksnap/src/main.rs: -------------------------------------------------------------------------------- 1 | // linksnap/src/main.rs 2 | 3 | mod links; 4 | mod route_handlers; 5 | mod state; 6 | 7 | use std::env; 8 | use log::info; 9 | use crate::state::State; 10 | use crate::route_handlers::{index, links, add_link, rm_link}; 11 | use actix_web::middleware::Logger; 12 | use actix_web::{http, server, App}; 13 | 14 | fn init_env() { 15 | env::set_var("RUST_LOG", "linksnap=info"); 16 | env::set_var("RUST_BACKTRACE", "1"); 17 | env_logger::init(); 18 | info!("Starting http server: 127.0.0.1:8080"); 19 | } 20 | 21 | fn main() { 22 | init_env(); 23 | let system = actix::System::new("linksnap"); 24 | let state = State::init(); 25 | 26 | let web_app = move || { 27 | App::with_state(state.clone()) 28 | .middleware(Logger::default()) 29 | .route("/", http::Method::GET, index) 30 | .route("/links", http::Method::GET, links) 31 | .route("/add", http::Method::POST, add_link) 32 | .route("/rm", http::Method::DELETE, rm_link) 33 | }; 34 | 35 | server::new(web_app).bind("127.0.0.1:8080").unwrap().start(); 36 | let _ = system.run(); 37 | } 38 | -------------------------------------------------------------------------------- /Chapter05/todolist_parser/src/error.rs: -------------------------------------------------------------------------------- 1 | // todolist_parser/src/error.rs 2 | 3 | use std::error::Error; 4 | use std::fmt; 5 | use std::fmt::Display; 6 | 7 | #[derive(Debug)] 8 | pub enum ParseErr { 9 | Malformed, 10 | Empty 11 | } 12 | 13 | #[derive(Debug)] 14 | pub struct ReadErr { 15 | pub child_err: Box 16 | } 17 | 18 | // Required by error trait 19 | impl Display for ReadErr { 20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 21 | write!(f, "Failed reading todo file") 22 | } 23 | } 24 | 25 | // Required by error trait 26 | impl Display for ParseErr { 27 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 28 | write!(f, "Todo list parsing failed") 29 | } 30 | } 31 | 32 | impl Error for ReadErr { 33 | fn description(&self) -> &str { 34 | "Todolist read failed: " 35 | } 36 | 37 | fn cause(&self) -> Option<&dyn Error> { 38 | Some(&*self.child_err) 39 | } 40 | } 41 | 42 | impl Error for ParseErr { 43 | fn description(&self) -> &str { 44 | "Todolist parse failed: " 45 | } 46 | 47 | fn cause(&self) -> Option<&Error> { 48 | None 49 | } 50 | } -------------------------------------------------------------------------------- /Chapter06/todolist_parser/src/error.rs: -------------------------------------------------------------------------------- 1 | // todolist_parser/src/error.rs 2 | 3 | use std::error::Error; 4 | use std::fmt; 5 | use std::fmt::Display; 6 | 7 | #[derive(Debug)] 8 | pub enum ParseErr { 9 | Malformed, 10 | Empty 11 | } 12 | 13 | #[derive(Debug)] 14 | pub struct ReadErr { 15 | pub child_err: Box 16 | } 17 | 18 | // Required by error trait 19 | impl Display for ReadErr { 20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 21 | write!(f, "Failed reading todo file") 22 | } 23 | } 24 | 25 | // Required by error trait 26 | impl Display for ParseErr { 27 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 28 | write!(f, "Todo list parsing failed") 29 | } 30 | } 31 | 32 | impl Error for ReadErr { 33 | fn description(&self) -> &str { 34 | "Todolist read failed: " 35 | } 36 | 37 | fn cause(&self) -> Option<&dyn Error> { 38 | Some(&*self.child_err) 39 | } 40 | } 41 | 42 | impl Error for ParseErr { 43 | fn description(&self) -> &str { 44 | "Todolist parse failed: " 45 | } 46 | 47 | fn cause(&self) -> Option<&Error> { 48 | None 49 | } 50 | } -------------------------------------------------------------------------------- /Chapter03/logic_gates/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Rahul Sharma 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 | -------------------------------------------------------------------------------- /Chapter05/rc_weak.rs: -------------------------------------------------------------------------------- 1 | // rc_weak.rs 2 | 3 | use std::rc::Rc; 4 | use std::rc::Weak; 5 | 6 | #[derive(Debug)] 7 | struct LinkedList { 8 | head: Option>> 9 | } 10 | 11 | #[derive(Debug)] 12 | struct LinkedListNode { 13 | next: Option>>, 14 | prev: Option>>, 15 | data: T 16 | } 17 | 18 | impl LinkedList { 19 | fn new() -> Self { 20 | LinkedList { head: None } 21 | } 22 | 23 | fn append(&mut self, data: T) -> Self { 24 | let new_node = Rc::new(LinkedListNode { 25 | data: data, 26 | next: self.head.clone(), 27 | prev: None 28 | }); 29 | 30 | match self.head.clone() { 31 | Some(node) => { 32 | node.prev = Some(Rc::downgrade(&new_node)); 33 | }, 34 | None => { 35 | } 36 | } 37 | 38 | LinkedList { 39 | head: Some(new_node) 40 | } 41 | } 42 | } 43 | 44 | fn main() { 45 | let list_of_nums = LinkedList::new().append(1).append(2).append(3); 46 | println!("nums: {:?}", list_of_nums); 47 | } 48 | -------------------------------------------------------------------------------- /Chapter08/actor_demo/src/main.rs: -------------------------------------------------------------------------------- 1 | // actix_demo/src/main.rs 2 | 3 | use actix::prelude::*; 4 | use tokio::timer::Delay; 5 | use std::time::Duration; 6 | use std::time::Instant; 7 | use futures::future::Future; 8 | use futures::future; 9 | 10 | struct Add(u32, u32); 11 | 12 | impl Message for Add { 13 | type Result = Result; 14 | } 15 | 16 | struct Adder; 17 | 18 | impl Actor for Adder { 19 | type Context = SyncContext; 20 | } 21 | 22 | impl Handler for Adder { 23 | type Result = Result; 24 | 25 | fn handle(&mut self, msg: Add, _: &mut Self::Context) -> Self::Result { 26 | let sum = msg.0 + msg.0; 27 | println!("Computed: {} + {} = {}",msg.0, msg.1, sum); 28 | Ok(msg.0 + msg.1) 29 | } 30 | } 31 | 32 | fn main() { 33 | System::run(|| { 34 | let addr = SyncArbiter::start(3, || Adder); 35 | for n in 5..10 { 36 | addr.do_send(Add(n, n+1)); 37 | } 38 | 39 | tokio::spawn(futures::lazy(|| { 40 | Delay::new(Instant::now() + Duration::from_secs(1)).then(|_| { 41 | System::current().stop(); 42 | future::ok::<(),()>(()) 43 | }) 44 | })); 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /Chapter05/rc_3.rs: -------------------------------------------------------------------------------- 1 | use std::rc::Rc; 2 | use std::rc::Weak; 3 | use std::cell::RefCell; 4 | 5 | #[derive(Debug)] 6 | struct LinkedList { 7 | head: Option>> 8 | } 9 | 10 | #[derive(Debug)] 11 | struct LinkedListNode { 12 | next: Option>>, 13 | prev: RefCell>>>, 14 | data: T 15 | } 16 | 17 | impl LinkedList { 18 | fn new() -> Self { 19 | LinkedList { head: None } 20 | } 21 | 22 | fn append(&mut self, data: T) -> Self { 23 | let new_node = Rc::new(LinkedListNode { 24 | data: data, 25 | next: self.head.clone(), 26 | prev: RefCell::new(None) 27 | }); 28 | 29 | match self.head.clone() { 30 | Some(node) => { 31 | let mut prev = node.prev.borrow_mut(); 32 | *prev = Some(Rc::downgrade(&new_node)); 33 | }, 34 | None => { 35 | } 36 | } 37 | 38 | LinkedList { 39 | head: Some(new_node) 40 | } 41 | } 42 | } 43 | 44 | fn main() { 45 | let list_of_nums = LinkedList::new().append(1).append(2).append(3); 46 | println!("nums: {:?}", list_of_nums); 47 | } 48 | -------------------------------------------------------------------------------- /Chapter03/logic_gates/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Demo example crate for Chapter 3 2 | //! This is a logic gates simulation crate built to demonstrate writing unit tests, integration tests, 3 | //! documentation tests. 4 | 5 | #![doc(html_logo_url = "https://d30y9cdsu7xlg0.cloudfront.net/png/411962-200.png")] 6 | 7 | /// Implements a boolean `and` gate taking as input two bits and returning a bit as its 8 | /// output 9 | pub fn and(a: u8, b: u8) -> u8 { 10 | match (a,b) { 11 | (1, 1) => 1, 12 | _ => 0 13 | } 14 | } 15 | 16 | /// Implements a boolean `xor` gate taking as input two bits and returning a bit as its 17 | /// output 18 | pub fn xor(a: u8, b: u8) -> u8 { 19 | match (a,b) { 20 | (1, 0) | (0, 1) => 1, 21 | _ => 0 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use crate::{xor, and}; 28 | #[test] 29 | fn test_and() { 30 | assert_eq!(1, and(1, 1)); 31 | assert_eq!(0, and(0, 1)); 32 | assert_eq!(0, and(1, 0)); 33 | assert_eq!(0, and(0,0)); 34 | } 35 | 36 | #[test] 37 | fn test_xor() { 38 | assert_eq!(1, xor(1, 0)); 39 | assert_eq!(0, xor(0, 0)); 40 | assert_eq!(0, xor(1, 1)); 41 | assert_eq!(1, xor(0, 1)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Chapter12/rudis_async/src/codec.rs: -------------------------------------------------------------------------------- 1 | // rudis_async/src/codec.rs 2 | 3 | use std::io; 4 | use bytes::BytesMut; 5 | use tokio_codec::{Decoder, Encoder}; 6 | use resp::{Value, Decoder as RespDecoder}; 7 | use std::io::BufReader; 8 | use std::str; 9 | 10 | pub struct RespCodec; 11 | 12 | impl Encoder for RespCodec { 13 | type Item = Vec; 14 | type Error = io::Error; 15 | 16 | fn encode(&mut self, msg: Vec, buf: &mut BytesMut) -> io::Result<()> { 17 | buf.reserve(msg.len()); 18 | buf.extend(msg); 19 | Ok(()) 20 | } 21 | } 22 | 23 | impl Decoder for RespCodec { 24 | type Item = Value; 25 | type Error = io::Error; 26 | 27 | fn decode(&mut self, buf: &mut BytesMut) -> io::Result> { 28 | let s = if let Some(n) = buf.iter().rposition(|b| *b == b'\n') { 29 | let client_query = buf.split_to(n + 1); 30 | 31 | match str::from_utf8(&client_query.as_ref()) { 32 | Ok(s) => s.to_string(), 33 | Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "invalid string")), 34 | } 35 | } else { 36 | return Ok(None); 37 | }; 38 | 39 | if let Ok(v) = RespDecoder::new(&mut BufReader::new(s.as_bytes())).decode() { 40 | Ok(Some(v)) 41 | } else { 42 | Ok(None) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Chapter13/linksnap/src/links.rs: -------------------------------------------------------------------------------- 1 | // linksnap/src/links.rs 2 | 3 | use std::collections::HashMap; 4 | use serde_derive::{Serialize, Deserialize}; 5 | use chrono::prelude::*; 6 | use crate::state::AddLink; 7 | 8 | pub type LinkId = i32; 9 | 10 | #[derive(Debug, Serialize, Deserialize)] 11 | pub struct Link { 12 | pub id: LinkId, 13 | pub title: String, 14 | pub url: String, 15 | pub added: String 16 | } 17 | 18 | #[derive(Serialize, Deserialize)] 19 | pub struct Links { 20 | last_id: LinkId, 21 | links: HashMap 22 | } 23 | 24 | impl Links { 25 | pub fn new() -> Self { 26 | Links { last_id: 0, links: HashMap::new() } 27 | } 28 | 29 | pub fn add_link(&mut self, add_link: AddLink) -> LinkId { 30 | let new_id = self.last_id + 1; 31 | self.last_id = new_id; 32 | let utc: DateTime = Utc::now(); 33 | self.links.insert(new_id, Link { 34 | id: new_id, 35 | title: add_link.title.to_string(), 36 | url: add_link.url.to_string(), 37 | added: utc.to_string() 38 | }); 39 | new_id 40 | } 41 | 42 | pub fn rm_link(&mut self, id: LinkId) -> Option { 43 | self.links.remove(&id).map(|_| id) 44 | } 45 | 46 | pub fn links(&self) -> String { 47 | serde_json::to_string_pretty(&self.links).unwrap() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Chapter05/todolist_parser/src/lib.rs: -------------------------------------------------------------------------------- 1 | // todolist_parser/src/lib.rs 2 | 3 | //! This crate provides an API to parse list of todos 4 | 5 | use std::fs::read_to_string; 6 | use std::path::Path; 7 | 8 | mod error; 9 | use error::ParseErr; 10 | use error::ReadErr; 11 | 12 | use std::error::Error; 13 | 14 | /// This struct contains a list of todos parsed as a Vec 15 | #[derive(Debug)] 16 | pub struct TodoList { 17 | tasks: Vec, 18 | } 19 | 20 | impl TodoList { 21 | pub fn get_todos

(path: P) -> Result> 22 | where 23 | P: AsRef, { 24 | let read_todos: Result> = read_todos(path); 25 | let parsed_todos = parse_todos(&read_todos?)?; 26 | Ok(parsed_todos) 27 | } 28 | } 29 | 30 | pub fn read_todos

(path: P) -> Result> 31 | where 32 | P: AsRef, 33 | { 34 | let raw_todos = read_to_string(path) 35 | .map_err(|e| ReadErr { 36 | child_err: Box::new(e), 37 | })?; 38 | Ok(raw_todos) 39 | } 40 | 41 | pub fn parse_todos(todo_str: &str) -> Result> { 42 | let mut tasks: Vec = vec![]; 43 | for i in todo_str.lines() { 44 | tasks.push(i.to_string()); 45 | } 46 | if tasks.is_empty() { 47 | Err(ParseErr::Empty.into()) 48 | } else { 49 | Ok(TodoList { tasks }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter06/todolist_parser/src/lib.rs: -------------------------------------------------------------------------------- 1 | // todolist_parser/src/lib.rs 2 | 3 | //! This crate provides an API to parse list of todos 4 | 5 | use std::fs::read_to_string; 6 | use std::path::Path; 7 | 8 | mod error; 9 | use error::ParseErr; 10 | use error::ReadErr; 11 | 12 | use std::error::Error; 13 | 14 | /// This struct contains a list of todos parsed as a Vec 15 | #[derive(Debug)] 16 | pub struct TodoList { 17 | tasks: Vec, 18 | } 19 | 20 | impl TodoList { 21 | pub fn get_todos

(path: P) -> Result> 22 | where 23 | P: AsRef, { 24 | let read_todos: Result> = read_todos(path); 25 | let parsed_todos = parse_todos(&read_todos?)?; 26 | Ok(parsed_todos) 27 | } 28 | } 29 | 30 | pub fn read_todos

(path: P) -> Result> 31 | where 32 | P: AsRef, 33 | { 34 | let raw_todos = read_to_string(path) 35 | .map_err(|e| ReadErr { 36 | child_err: Box::new(e), 37 | })?; 38 | Ok(raw_todos) 39 | } 40 | 41 | pub fn parse_todos(todo_str: &str) -> Result> { 42 | let mut tasks: Vec = vec![]; 43 | for i in todo_str.lines() { 44 | tasks.push(i.to_string()); 45 | } 46 | if tasks.is_empty() { 47 | Err(ParseErr::Empty.into()) 48 | } else { 49 | Ok(TodoList { tasks }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter07/custom_iterator.rs: -------------------------------------------------------------------------------- 1 | // custom_iterator.rs 2 | 3 | use std::usize; 4 | 5 | struct Primes { 6 | limit: usize 7 | } 8 | 9 | fn compute_primes(limit: usize) -> Vec { 10 | let mut sieve = vec![true; limit]; 11 | let mut m = 2; 12 | while m * m < limit { 13 | if sieve[m] { 14 | for i in (m * 2..limit).step_by(m) { 15 | sieve[i] = false; 16 | } 17 | } 18 | m += 1; 19 | } 20 | sieve 21 | } 22 | 23 | impl Primes { 24 | fn iter(&self) -> PrimesIter { 25 | PrimesIter { 26 | index: 2, 27 | computed: compute_primes(self.limit) 28 | } 29 | } 30 | 31 | fn new(limit: usize) -> Primes { 32 | Primes { limit } 33 | } 34 | } 35 | 36 | struct PrimesIter { 37 | index: usize, 38 | computed: Vec 39 | } 40 | 41 | impl Iterator for PrimesIter { 42 | type Item = usize; 43 | fn next(&mut self) -> Option { 44 | loop { 45 | self.index += 1; 46 | if self.index > self.computed.len() - 1 { 47 | return None; 48 | } else if self.computed[self.index] { 49 | return Some(self.index); 50 | } else { 51 | continue 52 | } 53 | } 54 | } 55 | } 56 | 57 | fn main() { 58 | let primes = Primes::new(100); 59 | for i in primes.iter() { 60 | print!("{}, ", i); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Chapter12/rudis_sync/src/main.rs: -------------------------------------------------------------------------------- 1 | // rudis_sync/src/main.rs 2 | 3 | use lazy_static::lazy_static; 4 | use resp::Decoder; 5 | use std::collections::HashMap; 6 | use std::env; 7 | use std::io::{BufReader, Write}; 8 | use std::net::Shutdown; 9 | use std::net::{TcpListener, TcpStream}; 10 | use std::sync::Mutex; 11 | 12 | mod commands; 13 | use crate::commands::process_client_request; 14 | 15 | type STORE = Mutex>; 16 | 17 | lazy_static! { 18 | static ref RUDIS_DB: STORE = Mutex::new(HashMap::new()); 19 | } 20 | 21 | fn handle_client(stream: TcpStream) { 22 | let mut stream = BufReader::new(stream); 23 | let decoder = Decoder::new(&mut stream).decode(); 24 | match decoder { 25 | Ok(v) => { 26 | let reply = process_client_request(v); 27 | stream.get_mut().write_all(&reply).unwrap(); 28 | } 29 | Err(e) => { 30 | println!("Invalid command: {:?}", e); 31 | let _ = stream.get_mut().shutdown(Shutdown::Both); 32 | } 33 | }; 34 | } 35 | 36 | fn main() { 37 | let addr = env::args() 38 | .skip(1) 39 | .next() 40 | .unwrap_or("127.0.0.1:6378".to_owned()); 41 | let listener = TcpListener::bind(&addr).unwrap(); 42 | println!("rudis_sync listening on {} ...", addr); 43 | 44 | for stream in listener.incoming() { 45 | let stream = stream.unwrap(); 46 | println!("New connection from: {:?}", stream); 47 | handle_client(stream); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Chapter01/exercise_word_counter.rs: -------------------------------------------------------------------------------- 1 | // Chapter 01 Exercise 2 | 3 | // A program that counts instances of words 4 | // in a text file given to it as its argument 5 | 6 | use std::env; 7 | use std::fs::File; 8 | use std::io::prelude::BufRead; 9 | use std::io::BufReader; 10 | 11 | #[derive(Debug)] 12 | struct WordCounter(HashMap); 13 | 14 | impl WordCounter { 15 | fn new() -> WordCounter { 16 | WordCounter(HashMap::new()); 17 | } 18 | 19 | fn increment(word: &str) { 20 | let key = word.to_string(); 21 | let count = self.0.entry(key).or_insert(0); 22 | *count += 1; 23 | } 24 | 25 | fn display(self) { 26 | for (key,value) in self.0.iter() { 27 | println!("{}: {}", key, value); 28 | } 29 | } 30 | } 31 | 32 | fn main() { 33 | let arguments: Vec = env::args().collect(); 34 | let filename = arguments[1]; 35 | println!("Processing file: {}", filename); 36 | 37 | let file = File::open(filenam).expect("Could not open file"); 38 | let reader = BufReader::new(file); 39 | 40 | let mut word_counter = WordCounter::new(); 41 | 42 | for line in reader.lines() { 43 | let line = line.expect("Could not read line"); 44 | let words = line.split(" "); 45 | for word in words { 46 | if word == "" { 47 | continue 48 | } else { 49 | word_counter.increment(word); 50 | } 51 | } 52 | } 53 | 54 | word_counter.display(); 55 | } 56 | -------------------------------------------------------------------------------- /Chapter12/rudis_async/src/main.rs: -------------------------------------------------------------------------------- 1 | // rudis_async/src/main.rs 2 | 3 | mod codec; 4 | use crate::codec::RespCodec; 5 | 6 | use lazy_static::lazy_static; 7 | use std::collections::HashMap; 8 | use std::net::SocketAddr; 9 | use std::sync::Mutex; 10 | use tokio::net::TcpListener; 11 | use tokio::net::TcpStream; 12 | use tokio::prelude::*; 13 | use tokio_codec::Decoder; 14 | use std::env; 15 | 16 | mod commands; 17 | use crate::commands::process_client_request; 18 | 19 | lazy_static! { 20 | static ref RUDIS_DB: Mutex> = Mutex::new(HashMap::new()); 21 | } 22 | 23 | fn main() -> Result<(), Box> { 24 | let addr = env::args() 25 | .skip(1) 26 | .next() 27 | .unwrap_or("127.0.0.1:6378".to_owned()); 28 | let addr = addr.parse::()?; 29 | 30 | let listener = TcpListener::bind(&addr)?; 31 | println!("rudis_async listening on: {}", addr); 32 | 33 | let server_future = listener 34 | .incoming() 35 | .map_err(|e| println!("failed to accept socket; error = {:?}", e)) 36 | .for_each(handle_client); 37 | 38 | tokio::run(server_future); 39 | Ok(()) 40 | } 41 | 42 | fn handle_client(client: TcpStream) -> Result<(), ()> { 43 | let (tx, rx) = RespCodec.framed(client).split(); 44 | let reply = rx.and_then(process_client_request); 45 | let task = tx.send_all(reply).then(|res| { 46 | if let Err(e) = res { 47 | eprintln!("failed to process connection; error = {:?}", e); 48 | } 49 | Ok(()) 50 | }); 51 | 52 | tokio::spawn(task); 53 | Ok(()) 54 | } 55 | -------------------------------------------------------------------------------- /Chapter14/src/singly_linked_list.rs: -------------------------------------------------------------------------------- 1 | use std::cell::RefCell; 2 | use std::rc::Rc; 3 | 4 | #[derive(Clone)] 5 | struct Node { 6 | value: String, 7 | next: Link, 8 | } 9 | 10 | type Link = Option>>; 11 | 12 | impl Node { 13 | fn new(value: String) -> Rc> { 14 | Rc::new(RefCell::new(Node { 15 | value: value, 16 | next: None, 17 | })) 18 | } 19 | } 20 | 21 | #[derive(Clone)] 22 | pub struct TransactionLog { 23 | head: Link, 24 | tail: Link, 25 | pub length: u64, 26 | } 27 | 28 | impl TransactionLog { 29 | pub fn new_empty() -> TransactionLog { 30 | TransactionLog { head: None, tail: None, length: 0 } 31 | } 32 | 33 | pub fn append(&mut self, value: String) { 34 | let new = Node::new(value); 35 | 36 | match self.tail.take() { 37 | Some(old) => old.borrow_mut().next = Some(new.clone()), 38 | None => self.head = Some(new.clone()) 39 | }; 40 | self.length += 1; 41 | self.tail = Some(new); 42 | } 43 | 44 | pub fn pop(&mut self) -> Option { 45 | self.head.take().map(|head| { 46 | if let Some(next) = head.borrow_mut().next.take() { 47 | self.head = Some(next); 48 | } else { 49 | self.tail.take(); 50 | } 51 | self.length -= 1; 52 | Rc::try_unwrap(head) 53 | .ok() 54 | .expect("Something is terribly wrong") 55 | .into_inner() 56 | .value 57 | }) 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/into_map_derive/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | extern crate proc_macro; 3 | use proc_macro::TokenStream; 4 | use quote::quote; 5 | use syn::{parse_macro_input, Data, DeriveInput, Fields}; 6 | 7 | #[proc_macro_derive(IntoMap)] 8 | pub fn into_map_derive(input: TokenStream) -> TokenStream { 9 | let mut insert_tokens = vec![]; 10 | let parsed_input: DeriveInput = parse_macro_input!(input); 11 | let struct_name = parsed_input.ident; 12 | match parsed_input.data { 13 | Data::Struct(s) => { 14 | if let Fields::Named(named_fields) = s.fields { 15 | let fields = named_fields.named; 16 | for f in fields { 17 | let field = f.ident.unwrap(); 18 | let insert_token = quote! { 19 | map.insert( 20 | stringify!(#field).to_string(), 21 | self.#field.to_string() 22 | ); 23 | }; 24 | insert_tokens.push(insert_token); 25 | } 26 | } 27 | } 28 | other => panic!("IntoMap is not yet implemented for: {:?}", other), 29 | } 30 | 31 | let tokens = quote! { 32 | use std::collections::BTreeMap; 33 | use into_map::IntoMap; 34 | 35 | impl IntoMap for #struct_name { 36 | /// Converts the given struct into a dynamic map 37 | fn into_map(&self) -> BTreeMap { 38 | let mut map = BTreeMap::new(); 39 | #(#insert_tokens)* 40 | map 41 | } 42 | } 43 | }; 44 | 45 | proc_macro::TokenStream::from(tokens) 46 | } 47 | -------------------------------------------------------------------------------- /Chapter21/src/prng.rs: -------------------------------------------------------------------------------- 1 | const S1_MOD: f32 = 30269f32; 2 | const S2_MOD: f32 = 30307f32; 3 | const S3_MOD: f32 = 30323f32; 4 | 5 | pub struct WichmannHillRng { 6 | s1: f32, 7 | s2: f32, 8 | s3: f32, 9 | } 10 | 11 | impl WichmannHillRng { 12 | fn new(s1: f32, s2: f32, s3: f32) -> WichmannHillRng { 13 | WichmannHillRng { 14 | s1: s1, 15 | s2: s2, 16 | s3: s3, 17 | } 18 | } 19 | 20 | pub fn seeded(seed: u32) -> WichmannHillRng { 21 | let t = seed; 22 | let s1 = (t % 29999) as f32; 23 | let s2 = (t % 29347) as f32; 24 | let s3 = (t % 29097) as f32; 25 | WichmannHillRng::new(s1, s2, s3) 26 | } 27 | 28 | pub fn next_f32(&mut self) -> f32 { 29 | self.s1 = (171f32 * self.s1) % S1_MOD; 30 | self.s2 = (172f32 * self.s2) % S2_MOD; 31 | self.s3 = (170f32 * self.s3) % S3_MOD; 32 | (self.s1 / S1_MOD + self.s2 / S2_MOD + self.s3 / S3_MOD) % 1f32 33 | } 34 | } 35 | 36 | pub struct LCG { 37 | xn: f32, 38 | m: f32, 39 | c: f32, 40 | a: f32, 41 | } 42 | 43 | impl LCG { 44 | fn seeded(seed: f32) -> LCG { 45 | LCG { 46 | xn: seed, 47 | // glibc defaults according to wikipedia 48 | m: 2e31, 49 | a: 1103515245f32, 50 | c: 12345f32, 51 | } 52 | } 53 | 54 | fn new(seed: f32, m: f32, a: f32, c: f32) -> LCG { 55 | LCG { 56 | xn: seed, 57 | m: m, 58 | a: a, 59 | c: c, 60 | } 61 | } 62 | 63 | fn next(&mut self) -> f32 { 64 | self.xn = (self.a * self.xn + self.c) % self.m; 65 | self.xn 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Chapter12/rudis_async/src/commands.rs: -------------------------------------------------------------------------------- 1 | // rudis_async/src/commands.rs 2 | 3 | use crate::RUDIS_DB; 4 | use resp::Value; 5 | use futures::{future, Future}; 6 | use std::io::Error; 7 | 8 | pub fn handle_get(v: Vec) -> Result { 9 | let v = v.iter().skip(1).collect::>(); 10 | let db_ref = RUDIS_DB.lock().unwrap(); 11 | let reply = if let Value::Bulk(ref s) = &v[0] { 12 | db_ref.get(s).map(|e| Value::String(e.to_string())).unwrap_or(Value::Null) 13 | } else { 14 | Value::Null 15 | }; 16 | Ok(reply) 17 | } 18 | 19 | pub fn handle_set(v: Vec) -> Result { 20 | let v = v.iter().skip(1).collect::>(); 21 | if v.is_empty() || v.len() < 2 { 22 | return Err(Value::Error("Expected 2 arguments for SET command".to_string())) 23 | } 24 | match (&v[0], &v[1]) { 25 | (Value::Bulk(k), Value::Bulk(v)) => { 26 | let _ = RUDIS_DB 27 | .lock() 28 | .unwrap() 29 | .insert(k.to_string(), v.to_string()); 30 | } 31 | _ => unimplemented!("SET not implemented for {:?}", v), 32 | } 33 | 34 | Ok(Value::String("OK".to_string())) 35 | } 36 | 37 | pub fn process_client_request(decoded_msg: Value) -> impl Future, Error = Error> { 38 | let reply = if let Value::Array(v) = decoded_msg { 39 | match &v[0] { 40 | Value::Bulk(ref s) if s == "GET" || s == "get" => handle_get(v), 41 | Value::Bulk(ref s) if s == "SET" || s == "set" => handle_set(v), 42 | other => unimplemented!("{:?} is not supported as of now", other), 43 | } 44 | } else { 45 | Err(Value::Error("Invalid Command".to_string())) 46 | }; 47 | 48 | future::ok(match reply { 49 | Ok(r) | Err(r) => r.encode(), 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /Chapter12/rudis_sync/src/commands.rs: -------------------------------------------------------------------------------- 1 | // rudis_sync/src/commands.rs 2 | 3 | use crate::RUDIS_DB; 4 | use resp::Value; 5 | 6 | pub fn handle_get(v: Vec) -> Result { 7 | let v = v.iter().skip(1).collect::>(); 8 | if v.is_empty() { 9 | return Err(Value::Error("Expected 1 argument for GET command".to_string())) 10 | } 11 | let db_ref = RUDIS_DB.lock().unwrap(); 12 | let reply = if let Value::Bulk(ref s) = &v[0] { 13 | db_ref.get(s).map(|e| Value::Bulk(e.to_string())).unwrap_or(Value::Null) 14 | } else { 15 | Value::Null 16 | }; 17 | Ok(reply) 18 | } 19 | 20 | pub fn handle_set(v: Vec) -> Result { 21 | let v = v.iter().skip(1).collect::>(); 22 | if v.is_empty() || v.len() < 2 { 23 | return Err(Value::Error("Expected 2 arguments for SET command".to_string())) 24 | } 25 | match (&v[0], &v[1]) { 26 | (Value::Bulk(k), Value::Bulk(v)) => { 27 | let _ = RUDIS_DB 28 | .lock() 29 | .unwrap() 30 | .insert(k.to_string(), v.to_string()); 31 | } 32 | _ => unimplemented!("SET not implemented for {:?}", v), 33 | } 34 | 35 | Ok(Value::String("OK".to_string())) 36 | } 37 | 38 | pub fn process_client_request(decoded_msg: Value) -> Vec { 39 | let reply = if let Value::Array(v) = decoded_msg { 40 | match &v[0] { 41 | Value::Bulk(ref s) if s == "GET" || s == "get" => handle_get(v), 42 | Value::Bulk(ref s) if s == "SET" || s == "set" => handle_set(v), 43 | other => unimplemented!("{:?} is not supported as of now", other), 44 | } 45 | } else { 46 | Err(Value::Error("Invalid Command".to_string())) 47 | }; 48 | 49 | match reply { 50 | Ok(r) | Err(r) => r.encode(), 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Chapter11/slog_demo/src/main.rs: -------------------------------------------------------------------------------- 1 | // slog_demo/main.rs 2 | 3 | #[macro_use] 4 | extern crate slog; 5 | extern crate slog_async; 6 | extern crate slog_json; 7 | extern crate rand; 8 | 9 | mod enemy; 10 | mod player; 11 | mod weapon; 12 | 13 | use player::Player; 14 | use enemy::Enemy; 15 | use rand::Rng; 16 | use std::thread; 17 | use slog::Drain; 18 | use slog::Logger; 19 | use slog_async::Async; 20 | use std::time::Duration; 21 | 22 | pub trait PlayingCharacter { 23 | fn shoot(&self); 24 | } 25 | 26 | struct Game { 27 | logger: Logger, 28 | player: Player, 29 | enemy: Enemy 30 | } 31 | 32 | impl Game { 33 | fn simulate(&mut self) { 34 | info!(self.logger, "Launching game!"); 35 | let enemy_or_player: Vec<&dyn PlayingCharacter> = vec![&self.enemy, &self.player]; 36 | loop { 37 | let mut rng = rand::thread_rng(); 38 | let a = rng.gen_range(500, 1000); 39 | thread::sleep(Duration::from_millis(a)); 40 | let player = enemy_or_player[{ 41 | if a % 2 == 0 {1} else {0} 42 | }]; 43 | player.shoot(); 44 | } 45 | } 46 | } 47 | 48 | fn main() { 49 | let drain = slog_json::Json::new(std::io::stdout()).add_default_keys() 50 | .build() 51 | .fuse(); 52 | let async_drain = Async::new(drain).build().fuse(); 53 | 54 | let game_info = format!("v{}", env!("CARGO_PKG_VERSION")); 55 | let root_log_context = o!("Super Cool Game" => game_info); 56 | let root_logger = Logger::root(async_drain, root_log_context); 57 | 58 | let mut game = Game { logger: root_logger.clone(), 59 | player: Player::new(&root_logger, "Bob"), 60 | enemy: Enemy::new(&root_logger, "Malice") }; 61 | game.simulate() 62 | } 63 | -------------------------------------------------------------------------------- /Chapter16/src/map.rs: -------------------------------------------------------------------------------- 1 | use crate::LocationInformation; 2 | 3 | type Entry = Vec<(K, V)>; 4 | 5 | pub type LocationCache = HashMap; 6 | 7 | pub struct HashMap 8 | where 9 | K: PartialEq + Clone, 10 | V: Clone, 11 | { 12 | hash_fn: Box usize)>, 13 | store: Box<[Entry]>, 14 | pub length: usize, 15 | } 16 | 17 | impl HashMap 18 | where 19 | K: PartialEq + Clone, 20 | V: Clone, 21 | { 22 | pub fn new(hash_fn: Box usize)>, length: usize) -> HashMap { 23 | HashMap { 24 | hash_fn: hash_fn, 25 | length: 0, 26 | store: vec![vec![]; length].into_boxed_slice(), 27 | } 28 | } 29 | 30 | pub fn get(&self, key: &K) -> Option { 31 | let h = (self.hash_fn)(key); 32 | let idx = h & (self.store.len() - 1); 33 | self.store[idx] 34 | .iter() 35 | .find(|e| e.0 == *key) 36 | .map(|e| e.1.clone()) 37 | } 38 | 39 | pub fn remove(&mut self, key: K) -> Option { 40 | let h = (self.hash_fn)(&key); 41 | let idx = h & (self.store.len() - 1); 42 | match self.store[idx].iter().position(|e| e.0 == key) { 43 | Some(pos) => { 44 | self.length -= 1; 45 | Some(self.store[idx].remove(pos).1) 46 | } 47 | _ => None, 48 | } 49 | } 50 | 51 | pub fn insert(&mut self, key: K, value: V) { 52 | let h = (self.hash_fn)(&key); 53 | let idx = h & (self.store.len() - 1); 54 | match self.store[idx].iter().position(|e| e.0 == key) { 55 | Some(pos) => self.store[idx][pos] = (key, value), 56 | None => { 57 | self.store[idx].push((key, value)); 58 | self.length += 1 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Chapter04/complex/src/lib.rs: -------------------------------------------------------------------------------- 1 | // complex/src/lib.rs 2 | 3 | use std::ops::Add; 4 | 5 | #[derive(Default, Debug, PartialEq, Copy, Clone)] 6 | struct Complex { 7 | // Real part 8 | re: T, 9 | // Complex part 10 | im: T 11 | } 12 | 13 | impl Complex { 14 | fn new(re: T, im: T) -> Self { 15 | Complex { re, im } 16 | } 17 | } 18 | 19 | impl> Add for Complex { 20 | type Output = Complex; 21 | fn add(self, rhs: Complex) -> Self::Output { 22 | Complex { re: self.re + rhs.re, im: self.im + rhs.im } 23 | } 24 | } 25 | 26 | impl From<(T, T)> for Complex { 27 | fn from(value: (T, T)) -> Complex { 28 | Complex { re: value.0, im: value.1 } 29 | } 30 | } 31 | 32 | use std::fmt::{Formatter, Display, Result}; 33 | 34 | impl Display for Complex { 35 | fn fmt(&self, f: &mut Formatter) -> Result { 36 | write!(f, "{} + {}i", self.re, self.im) 37 | } 38 | } 39 | 40 | #[cfg(test)] 41 | mod tests { 42 | use crate::Complex; 43 | #[test] 44 | fn complex_basics() { 45 | let first = Complex::new(3,5); 46 | let second: Complex = Complex::default(); 47 | assert_eq!(first.re, 3); 48 | assert_eq!(first.im, 5); 49 | assert!(second.re == second.im); 50 | } 51 | #[test] 52 | fn complex_addition() { 53 | let a = Complex::new(1,-2); 54 | let b = Complex::default(); 55 | let res = a + b; 56 | assert_eq!(res, a); 57 | } 58 | 59 | #[test] 60 | fn complex_from() { 61 | let a = (2345, 456); 62 | let complex = Complex::from(a); 63 | assert_eq!(complex.re, 2345); 64 | assert_eq!(complex.im, 456); 65 | } 66 | 67 | #[test] 68 | fn complex_display() { 69 | let my_imaginary = Complex::new(2345,456); 70 | println!("{}", my_imaginary); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/into_map_derive/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "into_map" 3 | version = "0.1.0" 4 | 5 | [[package]] 6 | name = "into_map_derive" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "into_map 0.1.0", 10 | "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", 12 | ] 13 | 14 | [[package]] 15 | name = "proc-macro2" 16 | version = "0.4.24" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | dependencies = [ 19 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "quote" 24 | version = "0.6.10" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | dependencies = [ 27 | "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 28 | ] 29 | 30 | [[package]] 31 | name = "syn" 32 | version = "0.15.22" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | dependencies = [ 35 | "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 37 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 38 | ] 39 | 40 | [[package]] 41 | name = "unicode-xid" 42 | version = "0.1.0" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | 45 | [metadata] 46 | "checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" 47 | "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" 48 | "checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7" 49 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 50 | -------------------------------------------------------------------------------- /Chapter13/linksnap/src/route_handlers.rs: -------------------------------------------------------------------------------- 1 | // linksnap/src/route_handlers.rs 2 | 3 | use actix_web::{Error, HttpRequest, HttpResponse}; 4 | 5 | use crate::state::{AddLink, GetLinks, RmLink}; 6 | use crate::State; 7 | use actix_web::AsyncResponder; 8 | use actix_web::FromRequest; 9 | use actix_web::HttpMessage; 10 | use actix_web::Query; 11 | use futures::Future; 12 | 13 | type ResponseFuture = Box>; 14 | 15 | macro_rules! server_err { 16 | ($msg:expr) => { 17 | Err(actix_web::error::ErrorInternalServerError($msg)) 18 | }; 19 | } 20 | 21 | pub fn index(_req: HttpRequest) -> HttpResponse { 22 | HttpResponse::from("Welcome to Linksnap API server") 23 | } 24 | 25 | pub fn add_link(req: HttpRequest) -> ResponseFuture { 26 | req.json() 27 | .from_err() 28 | .and_then(move |link: AddLink| { 29 | let state = req.state().get(); 30 | state.send(link).from_err().and_then(|e| match e { 31 | Ok(_) => Ok(HttpResponse::Ok().finish()), 32 | Err(_) => server_err!("Failed to add link"), 33 | }) 34 | }) 35 | .responder() 36 | } 37 | 38 | pub fn links(req: HttpRequest) -> ResponseFuture { 39 | let state = &req.state().get(); 40 | state 41 | .send(GetLinks) 42 | .from_err() 43 | .and_then(|res| match res { 44 | Ok(res) => Ok(HttpResponse::Ok().body(res)), 45 | Err(_) => server_err!("Failed to retrieve links"), 46 | }) 47 | .responder() 48 | } 49 | 50 | pub fn rm_link(req: HttpRequest) -> ResponseFuture { 51 | let params: Query = Query::extract(&req).unwrap(); 52 | let state = &req.state().get(); 53 | state 54 | .send(RmLink { id: params.id }) 55 | .from_err() 56 | .and_then(|e| match e { 57 | Ok(e) => Ok(HttpResponse::Ok().body(format!("{}", e))), 58 | Err(_) => server_err!("Failed to remove link"), 59 | }) 60 | .responder() 61 | } 62 | -------------------------------------------------------------------------------- /Chapter09/into_map_demo/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "into_map" 3 | version = "0.1.0" 4 | 5 | [[package]] 6 | name = "into_map_demo" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "into_map 0.1.0", 10 | "into_map_derive 0.1.0", 11 | ] 12 | 13 | [[package]] 14 | name = "into_map_derive" 15 | version = "0.1.0" 16 | dependencies = [ 17 | "into_map 0.1.0", 18 | "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "proc-macro2" 24 | version = "0.4.24" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | dependencies = [ 27 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 28 | ] 29 | 30 | [[package]] 31 | name = "quote" 32 | version = "0.6.10" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | dependencies = [ 35 | "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 36 | ] 37 | 38 | [[package]] 39 | name = "syn" 40 | version = "0.15.22" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | dependencies = [ 43 | "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 44 | "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 45 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 46 | ] 47 | 48 | [[package]] 49 | name = "unicode-xid" 50 | version = "0.1.0" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | 53 | [metadata] 54 | "checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" 55 | "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" 56 | "checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7" 57 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 58 | -------------------------------------------------------------------------------- /Chapter15/src/heap.rs: -------------------------------------------------------------------------------- 1 | use crate::MessageNotification; 2 | use std::boxed::Box; 3 | use std::mem; 4 | 5 | pub struct MessageChecker { 6 | pub length: usize, 7 | heap: Vec>, 8 | } 9 | 10 | impl MessageChecker { 11 | pub fn new_empty() -> MessageChecker { 12 | MessageChecker { 13 | length: 0, 14 | heap: vec![], 15 | } 16 | } 17 | 18 | fn swap(&mut self, pos1: usize, pos2: usize) { 19 | let m2 = self.heap[pos1 - 1].clone(); 20 | self.heap[pos1 - 1] = mem::replace(&mut self.heap[pos2 - 1], m2); 21 | } 22 | 23 | fn has_more_messages(&self, pos1: usize, pos2: usize) -> bool { 24 | let a = &self.heap[pos1 - 1]; 25 | let b = &self.heap[pos2 - 1]; 26 | a.no_messages >= b.no_messages 27 | } 28 | 29 | pub fn add(&mut self, notification: MessageNotification) { 30 | self.heap.push(Box::new(notification)); 31 | self.length = self.heap.len(); 32 | 33 | if self.length > 1 { 34 | let mut i = self.length; 35 | while i / 2 > 0 && self.has_more_messages(i, i / 2) { 36 | self.swap(i, i / 2); 37 | i /= 2; 38 | } 39 | } 40 | } 41 | 42 | pub fn pop(&mut self) -> Option { 43 | if self.length > 0 { 44 | let elem = self.heap.swap_remove(0); 45 | self.length = self.heap.len(); 46 | let mut i = 1; 47 | while i * 2 < self.length { 48 | let children = (i * 2, i * 2 + 1); 49 | i = if self.has_more_messages(children.0, children.1) { 50 | if self.has_more_messages(children.0, i) { 51 | self.swap(i, children.0); 52 | children.0 53 | } else { 54 | break; 55 | } 56 | } else { 57 | if self.has_more_messages(children.1, i) { 58 | self.swap(i, children.1); 59 | children.1 60 | } else { 61 | break; 62 | } 63 | } 64 | } 65 | Some(*elem) 66 | } else { 67 | None 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Chapter21/src/knapsack.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::max; 2 | 3 | #[derive(Debug, PartialEq)] 4 | pub struct Item { 5 | pub weight: u32, 6 | pub value: u32, 7 | } 8 | 9 | pub struct Knapsack { 10 | capacity: usize, 11 | } 12 | 13 | pub trait DynamicProgramming { 14 | fn fill(&self, items: Vec<&Item>) -> u64; 15 | } 16 | 17 | pub trait Backtracking { 18 | fn fill(&self, items: Vec<&Item>) -> u64; 19 | fn fill_r(&self, remaining: &[&Item], current_weight: usize) -> i64; 20 | } 21 | 22 | impl Knapsack { 23 | pub fn new(capacity: usize) -> Knapsack { 24 | Knapsack { capacity: capacity } 25 | } 26 | } 27 | 28 | impl Backtracking for Knapsack { 29 | 30 | fn fill(&self, items: Vec<&Item>) -> u64 { 31 | let value = self.fill_r(&items, 0); 32 | if value < 0 { 33 | 0 34 | } else { 35 | value as u64 36 | } 37 | } 38 | 39 | fn fill_r(&self, remaining: &[&Item], current_weight: usize) -> i64 { 40 | let w = current_weight; 41 | 42 | if w > self.capacity { 43 | return i64::min_value(); 44 | } 45 | 46 | if remaining.len() > 0 && w < self.capacity { 47 | let include = remaining[0].value as i64 48 | + self.fill_r(&remaining[1..], current_weight + remaining[0].weight as usize); 49 | let exclude = self.fill_r(&remaining[1..], current_weight); 50 | if include >= exclude { 51 | include 52 | } else { 53 | exclude 54 | } 55 | } else { 56 | 0 57 | } 58 | } 59 | 60 | } 61 | 62 | impl DynamicProgramming for Knapsack { 63 | 64 | fn fill(&self, items: Vec<&Item>) -> u64 { 65 | let mut cache = vec![vec![0u64; self.capacity + 1]; items.len() + 1]; 66 | for i in 1..items.len() + 1 { 67 | for w in 1..self.capacity + 1 { 68 | if items[i -1].weight as usize <= w { 69 | let prev_weight = w - (items[i - 1].weight as usize); 70 | cache[i][w] = max( 71 | items[i - 1].value as u64 + cache[i - 1][prev_weight], 72 | cache[i - 1][w], 73 | ); 74 | } else { 75 | cache[i][w] = cache[i - 1][w] 76 | } 77 | } 78 | } 79 | cache[items.len()][self.capacity] 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Chapter15/src/binary_search_tree.rs: -------------------------------------------------------------------------------- 1 | use crate::IoTDevice; 2 | use std::mem; 3 | 4 | type Tree = Option>; 5 | 6 | struct Node { 7 | pub dev: IoTDevice, 8 | left: Tree, 9 | right: Tree, 10 | } 11 | 12 | impl Node { 13 | pub fn new(dev: IoTDevice) -> Tree { 14 | Some(Box::new(Node { 15 | dev: dev, 16 | left: None, 17 | right: None, 18 | })) 19 | } 20 | } 21 | 22 | pub struct DeviceRegistry { 23 | root: Tree, 24 | pub length: u64, 25 | } 26 | 27 | impl DeviceRegistry { 28 | pub fn new_empty() -> DeviceRegistry { 29 | DeviceRegistry { 30 | root: None, 31 | length: 0, 32 | } 33 | } 34 | 35 | pub fn add(&mut self, device: IoTDevice) { 36 | self.length += 1; 37 | let root = mem::replace(&mut self.root, None); 38 | self.root = self.add_rec(root, device); 39 | } 40 | 41 | fn add_rec(&mut self, node: Tree, device: IoTDevice) -> Tree { 42 | match node { 43 | Some(mut n) => { 44 | if n.dev.numerical_id <= device.numerical_id { 45 | n.left = self.add_rec(n.left, device); 46 | } else { 47 | n.right = self.add_rec(n.right, device); 48 | } 49 | Some(n) 50 | } 51 | _ => Node::new(device), 52 | } 53 | } 54 | 55 | pub fn find(&self, numerical_id: u64) -> Option { 56 | self.find_r(&self.root, numerical_id) 57 | } 58 | 59 | fn find_r(&self, node: &Tree, numerical_id: u64) -> Option { 60 | match node { 61 | Some(n) => { 62 | if n.dev.numerical_id == numerical_id { 63 | Some(n.dev.clone()) 64 | } else if n.dev.numerical_id < numerical_id { 65 | self.find_r(&n.left, numerical_id) 66 | } else { 67 | self.find_r(&n.right, numerical_id) 68 | } 69 | } 70 | _ => None, 71 | } 72 | } 73 | 74 | pub fn walk(&self, callback: impl Fn(&IoTDevice) -> ()) { 75 | self.walk_in_order(&self.root, &callback); 76 | } 77 | 78 | fn walk_in_order(&self, node: &Tree, callback: &impl Fn(&IoTDevice) -> ()) { 79 | if let Some(n) = node { 80 | self.walk_in_order(&n.left, callback); 81 | callback(&n.dev); 82 | self.walk_in_order(&n.right, callback); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Chapter15/src/trie.rs: -------------------------------------------------------------------------------- 1 | use crate::IoTDevice; 2 | use std::boxed::Box; 3 | use std::collections::HashMap; 4 | use std::mem; 5 | use std::str::Chars; 6 | 7 | type Link = Box; 8 | 9 | struct Node { 10 | pub key: char, 11 | next: HashMap, 12 | pub value: Option, 13 | } 14 | 15 | impl Node { 16 | pub fn new(key: char, device: Option) -> Link { 17 | Box::new(Node { 18 | key: key, 19 | next: HashMap::new(), 20 | value: device, 21 | }) 22 | } 23 | } 24 | 25 | impl PartialEq for Node { 26 | fn eq(&self, other: &Node) -> bool { 27 | self.key == other.key 28 | } 29 | } 30 | 31 | pub struct BestDeviceRegistry { 32 | pub length: u64, 33 | root: HashMap, 34 | } 35 | 36 | impl BestDeviceRegistry { 37 | pub fn new_empty() -> BestDeviceRegistry { 38 | BestDeviceRegistry { 39 | length: 0, 40 | root: HashMap::new(), 41 | } 42 | } 43 | 44 | pub fn add(&mut self, device: IoTDevice) { 45 | let p = device.path.clone(); 46 | let mut path = p.chars(); 47 | 48 | if let Some(start) = path.next() { 49 | self.length += 1; 50 | let mut n = self.root.entry(start).or_insert(Node::new(start, None)); 51 | for c in path { 52 | let tmp = n.next.entry(c).or_insert(Node::new(c, None)); 53 | n = tmp; 54 | } 55 | n.value = Some(device); 56 | } 57 | } 58 | 59 | pub fn find(&self, path: &str) -> Option { 60 | let mut path = path.chars(); 61 | 62 | if let Some(start) = path.next() { 63 | self.root.get(&start).map_or(None, |mut n| { 64 | for c in path { 65 | match n.next.get(&c) { 66 | Some(ref tmp) => n = tmp, 67 | None => break, 68 | } 69 | } 70 | n.value.clone() 71 | }) 72 | } else { 73 | None 74 | } 75 | } 76 | 77 | pub fn walk(&self, callback: impl Fn(&IoTDevice) -> ()) { 78 | for r in self.root.values() { 79 | self.walk_r(&r, &callback); 80 | } 81 | } 82 | 83 | fn walk_r(&self, node: &Link, callback: &impl Fn(&IoTDevice) -> ()) { 84 | for n in node.next.values() { 85 | self.walk_r(&n, callback); 86 | } 87 | if let Some(ref dev) = node.value { 88 | callback(dev); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Chapter13/linksnap/src/state.rs: -------------------------------------------------------------------------------- 1 | // linksnap/src/state.rs 2 | 3 | use actix::Actor; 4 | use actix::SyncContext; 5 | use actix::Message; 6 | use actix::Handler; 7 | use actix_web::{error, Error}; 8 | use std::sync::{Arc, Mutex}; 9 | use crate::links::Links; 10 | use actix::Addr; 11 | use serde_derive::{Serialize, Deserialize}; 12 | use actix::SyncArbiter; 13 | 14 | const DB_THREADS: usize = 3; 15 | 16 | #[derive(Clone)] 17 | pub struct Db { 18 | pub inner: Arc> 19 | } 20 | 21 | impl Db { 22 | pub fn new(s: Arc>) -> Db { 23 | Db { inner: s } 24 | } 25 | } 26 | 27 | impl Actor for Db { 28 | type Context = SyncContext; 29 | } 30 | 31 | #[derive(Clone)] 32 | pub struct State { 33 | pub inner: Addr 34 | } 35 | 36 | impl State { 37 | pub fn init() -> Self { 38 | let state = Arc::new(Mutex::new(Links::new())); 39 | let state = SyncArbiter::start(DB_THREADS, move || Db::new(state.clone())); 40 | let state = State { 41 | inner: state 42 | }; 43 | state 44 | } 45 | 46 | pub fn get(&self) -> &Addr { 47 | &self.inner 48 | } 49 | } 50 | 51 | pub struct GetLinks; 52 | 53 | impl Message for GetLinks { 54 | type Result = Result; 55 | } 56 | 57 | impl Handler for Db { 58 | type Result = Result; 59 | fn handle(&mut self, _new_link: GetLinks, _: &mut Self::Context) -> Self::Result { 60 | Ok(self.inner.lock().unwrap().links()) 61 | } 62 | } 63 | 64 | #[derive(Debug, Serialize, Deserialize)] 65 | pub struct AddLink { 66 | pub title: String, 67 | pub url: String 68 | } 69 | 70 | impl Message for AddLink { 71 | type Result = Result<(), Error>; 72 | } 73 | 74 | impl Handler for Db { 75 | type Result = Result<(), Error>; 76 | 77 | fn handle(&mut self, new_link: AddLink, _: &mut Self::Context) -> Self::Result { 78 | let mut db_ref = self.inner.lock().unwrap(); 79 | db_ref.add_link(new_link); 80 | Ok(()) 81 | } 82 | } 83 | 84 | #[derive(Serialize, Deserialize)] 85 | pub struct RmLink { 86 | pub id: i32 87 | } 88 | 89 | impl Message for RmLink { 90 | type Result = Result; 91 | } 92 | 93 | impl Handler for Db { 94 | type Result = Result; 95 | fn handle(&mut self, link: RmLink, _: &mut Self::Context) -> Self::Result { 96 | let mut db_ref = self.inner.lock().unwrap(); 97 | db_ref.rm_link(link.id).ok_or(error::ErrorInternalServerError("Failed to remove link")) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [![GitHub issues](https://img.shields.io/github/issues/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide.svg)](https://github.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/issues) 5 | [![GitHub forks](https://img.shields.io/github/forks/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide.svg)](https://github.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/network) 6 | [![GitHub stars](https://img.shields.io/github/stars/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide.svg)](https://github.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/stargazers) 7 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/PacktPublishing/The-Complete-Rust-Programming-Reference-Guide/pulls) 8 | 9 | 10 | 11 | # The Complete Rust Programming Reference Guide 12 | This Learning Path is your easy reference to mastering Rust programming. It begins with an introduction to Rust data structures and algorithms and covers the entire spectrum, including memory safety, type system, concurrency, and other features of Rust 2018. 13 | 14 | 15 | ## What you will learn 16 | * Design and implement complex data structures in Rust 17 | * Create and use well-tested and reusable components with Rust 18 | * Understand the basics of multithreaded programming and advanced algorithm design 19 | * Explore application profiling based on benchmarking and testing 20 | * Study and apply best practices and strategies in error handling 21 | * Create efficient web applications with the Actix-web framework 22 | * Use Diesel for type-safe database interactions in your web application 23 | 24 | 25 | 26 | 27 | ### Hardware requirements 28 | For an optimal student experience, we recommend the following hardware configuration: 29 | * **Processor**: 2.6 GHz or higher multi-core processor 30 | * **Memory**: 8GB RAM 31 | * **Hard disk**: 30GB or more 32 | * An Internet connection 33 | 34 | 35 | 36 | ### Software requirements 37 | You'll also need the following software installed: 38 | * Microsoft's Visual Studio Code (https://code.visualstudio.com/), arguably one of the best Rust code editors 39 | * Rust support for Visual Studio Code via a plugin (https://github.com/rust-lang/rls-vscode) 40 | * Rust Language Server (RLS), found at https://github.com/rust-lang/rls-vscode, installed via rustup (https://rustup.rs/) 41 | * Debugging support using the LLDB frontend plugin (https://github.com/vadimcn/vscode-lldb) for Visual Studio Code 42 | ### Download a free PDF 43 | 44 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
45 |

https://packt.link/free-ebook/9781838828103

-------------------------------------------------------------------------------- /Chapter13/hyperurl/src/service.rs: -------------------------------------------------------------------------------- 1 | // hyperurl/src/service.rs 2 | 3 | use std::sync::RwLock; 4 | use std::collections::HashMap; 5 | use std::sync::{Arc}; 6 | use std::str; 7 | use hyper::Request; 8 | use hyper::{Body, Response}; 9 | use hyper::rt::{Future, Stream}; 10 | use hyper::Method; 11 | use hyper::StatusCode; 12 | 13 | use lazy_static::lazy_static; 14 | use log::info; 15 | 16 | use crate::shortener::shorten_url; 17 | 18 | use futures::future; 19 | 20 | use crate::index::INDEX_PAGE; 21 | use crate::LISTEN_ADDR; 22 | 23 | type UrlDb = Arc>>; 24 | type BoxFut = Box, Error = hyper::Error> + Send>; 25 | 26 | lazy_static! { 27 | static ref SHORT_URLS: UrlDb = Arc::new(RwLock::new(HashMap::new())); 28 | } 29 | 30 | pub(crate) fn url_service(req: Request) -> BoxFut { 31 | 32 | match (req.method(), req.uri().path()) { 33 | (&Method::GET, "/") => { 34 | let reply = Response::new(Body::from(format!("{}",INDEX_PAGE))); 35 | Box::new(future::ok(reply)) 36 | } 37 | (&Method::GET, _) => { 38 | let url_db = SHORT_URLS.read().unwrap(); 39 | let uri = req.uri().to_string(); 40 | let short_url = format!("{}{}", LISTEN_ADDR, uri); 41 | let long_url = url_db.get(&short_url); 42 | println!("LONG URL {:?}",long_url); 43 | let reply = match long_url { 44 | Some(url) => { 45 | info!("Redirecting from {} to {}", short_url, url); 46 | Response::builder().status(StatusCode::TEMPORARY_REDIRECT) 47 | .header("Location", url.to_string()).body(Body::empty()).unwrap() 48 | } 49 | None => { 50 | Response::builder() 51 | .status(StatusCode::NOT_FOUND) 52 | .body(Body::from(format!("Bad URI: {:?}", uri))).unwrap() 53 | } 54 | }; 55 | Box::new(future::ok(reply)) 56 | } 57 | (&Method::POST, "/shorten") => { 58 | info!("Received request from : {:?}", req.headers()); 59 | let reply = req.into_body().concat2().map(move |chunk| { 60 | let c = chunk.iter().cloned().collect::>(); 61 | let url_to_shorten = str::from_utf8(&c).unwrap(); 62 | let short_url = shorten_url(url_to_shorten); 63 | let reply = Response::new(Body::from(format!("{}", &short_url))); 64 | SHORT_URLS.write().unwrap().insert(short_url, url_to_shorten.to_string()); 65 | reply 66 | }); 67 | Box::new(reply) 68 | } 69 | (_, _) => { 70 | let no_route = Response::new(Body::from("No route handler for this path")); 71 | Box::new(future::ok(no_route)) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Chapter14/src/dynamic_array.rs: -------------------------------------------------------------------------------- 1 | use std::boxed::Box; 2 | use std::cmp; 3 | use std::cell::Cell; 4 | 5 | const MIN_SIZE: usize = 10; 6 | 7 | type Node = Option; 8 | 9 | pub struct TimestampSaver { 10 | buf: Box<[Node]>, 11 | cap: usize, 12 | pub length: usize, 13 | } 14 | 15 | impl TimestampSaver { 16 | pub fn new_empty() -> TimestampSaver { 17 | TimestampSaver { 18 | buf: Box::new([None; MIN_SIZE]), 19 | length: 0, 20 | cap: MIN_SIZE, 21 | } 22 | } 23 | 24 | fn grow(&mut self, min_cap: usize) { 25 | let old_cap = self.buf.len(); 26 | let mut new_cap = old_cap + (old_cap >> 1); 27 | 28 | new_cap = cmp::max(new_cap, min_cap); 29 | new_cap = cmp::min(new_cap, usize::max_value()); 30 | let current = self.buf.clone(); 31 | self.cap = new_cap; 32 | 33 | self.buf = vec![None; new_cap].into_boxed_slice(); 34 | self.buf[..current.len()].clone_from_slice(¤t); 35 | } 36 | 37 | pub fn append(&mut self, value: u64) { 38 | if self.length == self.cap { 39 | self.grow(self.length + 1); 40 | } 41 | self.buf[self.length] = Some(value); 42 | self.length += 1; 43 | } 44 | 45 | pub fn at(&mut self, index: usize) -> Node { 46 | if self.length > index { 47 | self.buf[index] 48 | } else { 49 | None 50 | } 51 | } 52 | } 53 | 54 | impl IntoIterator for TimestampSaver { 55 | type Item = u64; 56 | type IntoIter = ListIterator; 57 | 58 | fn into_iter(self) -> Self::IntoIter { 59 | ListIterator::new(0, self.buf) 60 | } 61 | } 62 | 63 | pub struct ListIterator { 64 | current: usize, 65 | data: Box<[Node]>, 66 | } 67 | 68 | impl ListIterator { 69 | fn new(index: usize, buf: Box<[Node]>) -> ListIterator { 70 | ListIterator { 71 | current: index, 72 | data: buf, 73 | } 74 | } 75 | } 76 | 77 | impl Iterator for ListIterator { 78 | type Item = u64; 79 | 80 | fn next(&mut self) -> Option { 81 | if self.current < self.data.len() { 82 | let item = self.data[self.current]; 83 | self.current += 1; 84 | item 85 | } else { 86 | None 87 | } 88 | } 89 | } 90 | 91 | impl DoubleEndedIterator for ListIterator { 92 | fn next_back(&mut self) -> Option { 93 | if self.current < self.data.len() { 94 | let item = self.data[self.current]; 95 | if self.current == 0 { 96 | self.current = self.data.len() - 1; 97 | } else { 98 | self.current -= 1; 99 | } 100 | item 101 | } else { 102 | None 103 | } 104 | } 105 | } 106 | --------------------------------------------------------------------------------