diff --git a/.gitignore b/.gitignore index 0abc86b6..0f74a765 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ /.vscode/ /*.iml .DS_Store - +Cargo.lock /target/ diff --git a/.markdown-link-check.json b/.markdown-link-check.json index efb33341..3648de60 100644 --- a/.markdown-link-check.json +++ b/.markdown-link-check.json @@ -13,6 +13,8 @@ "ignorePatterns": [{ "pattern": "^!--" },{ + "pattern": "^https://aayushyavajpayee.substack.com" + }, { "pattern": "^https://github.com/instrumentisto/rust-incubator/generate" }, { "pattern": "^https://crates.io/search\\?" @@ -22,6 +24,8 @@ "pattern": "^https://dl.acm.org" }, { "pattern": "^https://dpc.pw" + }, { + "pattern": "^https://kerkour.com" }, { "pattern": "^https://www.aspecto.io" }, { diff --git a/0_vocabulary/README.md b/0_vocabulary/README.md index e387d229..d1fa70af 100644 --- a/0_vocabulary/README.md +++ b/0_vocabulary/README.md @@ -1,4 +1,4 @@ -Step 0: Building Up an Vocabulary +Chapter 0: Building Up an Vocabulary ======================================== __Estimated time__: 4 days @@ -14,6 +14,8 @@ Read through [Cargo Book] and become familiar with [Cargo] and its workspaces. After completing these steps, you should be able to answer (and understand why) the following questions: - What [memory model][31] [Rust] has? Is it single-threaded or multi-threaded? Is it synchronous or asynchronous? What are the memory layouts of `Box` and `Vector`? What are a heap and a stack? Where, but on heap and stack data could live in RAM? - What runtime [Rust] has? Does it use a GC (garbage collector)? +- What is special about slice? What is the layout of Rust standard data types? Difference between fat and thin pointers? +- Why does [Rust] have `&str` and `String` types? How do they differ? When should you use them? Why str slice coexists with slice? What is the difference between `String` and `Vec`? - What static typing means? What are the benefits of using it? Weak vs strong typing? Implicit vs explicit typing? - What are generics and parametric polymorphism? Which problems do they solve? - What are nominative typing and structural typing? What is the difference? @@ -28,8 +30,6 @@ After completing these steps, you should be able to answer (and understand why) - What is an iterator? What is a collection? How do they differ? How are they used? - What are macros? Which problems do they solve? What is the difference between declarative and procedural macro? - How code is tested in [Rust]? Where should you put tests and why? -- What is special about slice? What is the layout of Rust standard data types? Difference between fat and thin pointers? -- Why does [Rust] have `&str` and `String` types? How do they differ? When should you use them? Why str slice coexists with slice? What is the difference between `String` and `Vec`? - Is [Rust] an OOP language? Is it possible to use SOLID/GRASP? Does it have inheritance? Is Rust a functional language? What variance rules does Rust have? After you are done, notify your lead in an appropriate PR (pull request), and they will examine what you have learned. @@ -37,7 +37,7 @@ After you are done, notify your lead in an appropriate PR (pull request), and th _Additional_ articles, which may help to understand the above topic better: - [Chris Morgan: Rust ownership, the hard way][1] - [Adolfo Ochagavía: You are holding it wrong][23] -- [Vikram Fugro: Beyond Pointers: How Rust outshines C++ with its Borrow Checker][30] +- [Vikram Fugro: Beyond Pointers: How Rust outshines C++ with its Borrow Checker][29] - [HashRust: A guide to closures in Rust][24] - [Ludwig Stecher: Rusts Module System Explained][2] - [Tristan Hume: Models of Generics and Metaprogramming: Go, Rust, Swift, D and More][3] @@ -58,7 +58,7 @@ _Additional_ articles, which may help to understand the above topic better: - [Auto-trait definition][18] - [Georgios Antonopoulos: Rust vs Common C++ Bugs][21] - [Yurii Shymon: True Observer Pattern with Unsubscribe mechanism using Rust][22] -- [Asynchronous vs Multithreading][29] + Additional: - [Rust API guidline checklist][19] @@ -86,7 +86,7 @@ Additional: [9]: https://www.thecodedmessage.com/posts/raii [10]: https://vojtechkral.github.io/blag/rust-drop-order/ [11]: https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md -[12]: https://www.youtube.com/watch?v=rDoqT-a6UFg +[12]: https://youtu.be/7_o-YRxf_cc?si=gSVQ6wWSnr2le6rc [13]: https://www.reddit.com/r/rust/comments/lvtzri/confused_about_package_vs_crate_terminology/ [14]: https://rustwiki.org/en/book/ch07-01-packages-and-crates.html [16]: https://github.com/integer32llc/rust-playground/blob/master/compiler/base/Cargo.toml @@ -105,3 +105,4 @@ Additional: [29]: https://github.com/Learn-Together-Pro/ComputerScience/blob/master/gcs/cheatsheets.md#asynchronous-vs-multithreading [30]: https://dev.to/vikram2784/beyond-pointers-how-rust-outshines-c-with-its-borrow-checker-1mad [31]: https://en.wikipedia.org/wiki/Memory_model_(programming) + diff --git a/1_concepts/1_1_default_clone_copy/Cargo.toml b/1_concepts/1_1_default_clone_copy/Cargo.toml index afc5bfe7..9cc0e1e0 100644 --- a/1_concepts/1_1_default_clone_copy/Cargo.toml +++ b/1_concepts/1_1_default_clone_copy/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_1" +name = "task_1_1" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_1_default_clone_copy/README.md b/1_concepts/1_1_default_clone_copy/README.md index e13a52cb..5e9040f3 100644 --- a/1_concepts/1_1_default_clone_copy/README.md +++ b/1_concepts/1_1_default_clone_copy/README.md @@ -1,4 +1,4 @@ -Step 1.1: Default values, cloning and copying +Task 1.1: Default values, cloning and copying ============================================= diff --git a/1_concepts/1_2_box_pin/Cargo.toml b/1_concepts/1_2_box_pin/Cargo.toml index 074a72fe..ae98f38a 100644 --- a/1_concepts/1_2_box_pin/Cargo.toml +++ b/1_concepts/1_2_box_pin/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_2" +name = "task_1_2" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_2_box_pin/README.md b/1_concepts/1_2_box_pin/README.md index f00f0b89..fdfe46e1 100644 --- a/1_concepts/1_2_box_pin/README.md +++ b/1_concepts/1_2_box_pin/README.md @@ -1,4 +1,4 @@ -Step 1.2: Boxing and pinning +Task 1.2: Boxing and pinning ============================ @@ -42,6 +42,7 @@ For better understanding [`Pin`] purpose, design, limitations and use cases read - [Alice Ryhl answers on "Pin tutorial are confusing me"][9] - [Rust Forum: Why is it unsafe to pin a shared reference?][11] - [Ohad Ravid: Put a Pin on That][12] +- [Razieh Behjati: Leaky Abstractions and a Rusty Pin][13] @@ -59,10 +60,9 @@ __Estimated time__: 1 day #### Important: ##### THERE HAS TO BE NO `unsafe` CODE (DON'T USE `unsafe`) > - `mut_me_somehow` must mutate self somehow. - > - You can add trait bounds to the types. + > - You can add trait bounds to the types. (using `Unpin` trait bound is not allowed) > - Write simple tests to demonstrate mut_me_somehow. > - you may use modules to avoid conflicting implementations - ```rust trait SayHi: fmt::Debug { @@ -132,3 +132,4 @@ After completing everything above, you should be able to answer (and understand [10]: https://www.sobyte.net/post/2022-07/rust-pin-unpin [11]: https://users.rust-lang.org/t/why-is-it-unsafe-to-pin-a-shared-reference/40309 [12]: https://ohadravid.github.io/posts/2023-07-put-a-pin-on-that +[13]: https://itnext.io/leaky-abstractions-and-a-rusty-pin-fbf3b84eea1f diff --git a/1_concepts/1_3_rc_cell/Cargo.toml b/1_concepts/1_3_rc_cell/Cargo.toml index 916527aa..d75e3132 100644 --- a/1_concepts/1_3_rc_cell/Cargo.toml +++ b/1_concepts/1_3_rc_cell/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_3" +name = "task_1_3" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_3_rc_cell/README.md b/1_concepts/1_3_rc_cell/README.md index 451d0f09..f02c1107 100644 --- a/1_concepts/1_3_rc_cell/README.md +++ b/1_concepts/1_3_rc_cell/README.md @@ -1,4 +1,4 @@ -Step 1.3: Shared ownership and interior mutability +Task 1.3: Shared ownership and interior mutability ================================================== diff --git a/1_concepts/1_4_cow/Cargo.toml b/1_concepts/1_4_cow/Cargo.toml index fec07fa4..dd1deb5b 100644 --- a/1_concepts/1_4_cow/Cargo.toml +++ b/1_concepts/1_4_cow/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_4" +name = "task_1_4" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_4_cow/README.md b/1_concepts/1_4_cow/README.md index 4b9528dc..92c0e160 100644 --- a/1_concepts/1_4_cow/README.md +++ b/1_concepts/1_4_cow/README.md @@ -1,4 +1,4 @@ -Step 1.4: Clone-on-write +Task 1.4: Clone-on-write ======================== diff --git a/1_concepts/1_5_convert_cast_deref/Cargo.toml b/1_concepts/1_5_convert_cast_deref/Cargo.toml index 39b0ea6a..132ae3ce 100644 --- a/1_concepts/1_5_convert_cast_deref/Cargo.toml +++ b/1_concepts/1_5_convert_cast_deref/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_5" +name = "task_1_5" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_5_convert_cast_deref/README.md b/1_concepts/1_5_convert_cast_deref/README.md index 603f074a..85d20809 100644 --- a/1_concepts/1_5_convert_cast_deref/README.md +++ b/1_concepts/1_5_convert_cast_deref/README.md @@ -1,4 +1,4 @@ -Step 1.5: Conversions, casting and dereferencing +Task 1.5: Conversions, casting and dereferencing ================================================ As [Rust] is a [strongly typed][1] language, all type conversions must be performed explicitly in the code. As [Rust] has a rich type system (programming logic and semantics are mostly expressed in types rather than in values), type conversions are inevitable in almost every single line of code. Fortunately, [Rust] offers [well-designed type conversion capabilities][`std::convert`], which are quite ergonomic, intuitive and are pleasant to use. diff --git a/1_concepts/1_6_dispatch/Cargo.toml b/1_concepts/1_6_dispatch/Cargo.toml index 7952cce9..9f68df71 100644 --- a/1_concepts/1_6_dispatch/Cargo.toml +++ b/1_concepts/1_6_dispatch/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_6" +name = "task_1_6" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_6_dispatch/README.md b/1_concepts/1_6_dispatch/README.md index 73ec8a2f..604d7fee 100644 --- a/1_concepts/1_6_dispatch/README.md +++ b/1_concepts/1_6_dispatch/README.md @@ -1,11 +1,11 @@ -Step 1.6: Static and dynamic dispatch +Task 1.6: Static and dynamic dispatch ===================================== [Static][1] and [dynamic][2] dispatches are important concepts to understand how your code is compiled and works in runtime, and how you can solve certain day-to-day coding problems (related to polymorphism). __[Static dispatch][1]__ (also called "early binding") __happens only at compile time__. The compiler generates separate code for each concrete type that is used. In [Rust] static dispatch is a __default way for polymorphism__ and is introduced simply by generics (parametric polymorphism): `MyType`. -__[Dynamic dispatch][2]__ (sometimes called "late binding") __happens at runtime__. The concrete used __[type is erased][4] at compile time__, so compiler doesn't know it, therefore generates `vtable` which dispatches call at runtime and __comes with a performance penalty__. In [Rust] dynamic dispatch is introduced via [trait objects][3]: `&dyn MyTrait`, `Box`. +__[Dynamic dispatch][2]__ (sometimes called "late binding") __happens at runtime__. The concrete used __[type is erased][4] at compile time__, so compiler doesn't know it, therefore generates [vtable] which dispatches call at runtime and __comes with a performance penalty__. In [Rust] dynamic dispatch is introduced via [trait objects][3]: `&dyn MyTrait`, `Box`. You _have to_ use [dynamic dispatch][2] in situations where [type erasure][4] is required. If the problem can be solved with a [static dispatch][1] then you'd better to do so to avoid performance penalties. The most common example when you cannot use [static dispatch][1] and have to go with [dynamic dispatch][2] are _heterogeneous_ collections (where each item is potentially a different concrete type, but each one implements `MyTrait`). @@ -18,7 +18,7 @@ For better understanding [static][1] and [dynamic][2] dispatches purpose, design - [Nicholas Matsakis: Dyn async traits, part 2][17] - [Armin Ronacher: Rust Any Part 1: Extension Maps in Rust][18] - [Armin Ronacher: Rust Any Part 2: As-Any Hack][19] - +- [Dynamic Dispatch Representation][21] @@ -187,6 +187,7 @@ After completing everything above, you should be able to answer (and understand [enum_dispatch]: https://docs.rs/enum_dispatch [momo]: https://github.com/llogiq/momo [Rust]: https://www.rust-lang.org +[vtable]: https://en.wikipedia.org/wiki/Virtual_method_table [1]: https://en.wikipedia.org/wiki/Static_dispatch [2]: https://en.wikipedia.org/wiki/Dynamic_dispatch @@ -204,3 +205,4 @@ After completing everything above, you should be able to answer (and understand [18]: https://lucumr.pocoo.org/2022/1/6/rust-extension-map [19]: https://lucumr.pocoo.org/2022/1/7/as-any-hack [20]: https://medium.com/digitalfrontiers/rust-dynamic-dispatching-deep-dive-236a5896e49b +[21]: https://www.cs.brandeis.edu/~cs146a/rust/doc-02-21-2015/book/static-and-dynamic-dispatch.html#representation diff --git a/1_concepts/1_7_sized/Cargo.toml b/1_concepts/1_7_sized/Cargo.toml index b351be22..9131f66c 100644 --- a/1_concepts/1_7_sized/Cargo.toml +++ b/1_concepts/1_7_sized/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_7" +name = "task_1_7" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_7_sized/README.md b/1_concepts/1_7_sized/README.md index 51873664..e4079d54 100644 --- a/1_concepts/1_7_sized/README.md +++ b/1_concepts/1_7_sized/README.md @@ -1,4 +1,4 @@ -Step 1.7: `Sized` and `?Sized` types +Task 1.7: `Sized` and `?Sized` types ==================================== Most types in [Rust] have a particular size, in bytes, that is knowable at compile time. For example, an `i32` is 32 bits big, or 4 bytes. However, there are some types which are useful to express, but do not have a defined size (called "unsized" or "dynamically sized" types). One example is `[T]`: it represents a certain number of `T` in a sequence, but we don’t know how many there are, so the size is not known. diff --git a/1_concepts/1_8_thread_safety/Cargo.toml b/1_concepts/1_8_thread_safety/Cargo.toml index f207b109..674a1cf8 100644 --- a/1_concepts/1_8_thread_safety/Cargo.toml +++ b/1_concepts/1_8_thread_safety/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_8" +name = "task_1_8" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_8_thread_safety/README.md b/1_concepts/1_8_thread_safety/README.md index 7ed1658d..ce619671 100644 --- a/1_concepts/1_8_thread_safety/README.md +++ b/1_concepts/1_8_thread_safety/README.md @@ -1,4 +1,4 @@ -Step 1.8: Thread safety +Task 1.8: Thread safety ======================= [Rust] has [`Send`] and [`Sync`] marker traits which are fundamental for concurrency and thread safety story in [Rust] and represent one of [fearless concurrency][2] corner stones (which allow to [avoid data races][1] at compile time). @@ -13,6 +13,7 @@ For better understanding [`Send`]/[`Sync`] purpose, design, limitations and use - [nyanpasu64: An unsafe tour of Rust's Send and Sync][6] - [Josh Haberman: Thread Safety in C++ and Rust][7] - [Cliff L. Biffle: Safely writing code that isn't thread-safe][8] +- [Louis Dureuil: Too dangerous for C++][10] @@ -59,3 +60,4 @@ After completing everything above, you should be able to answer (and understand [7]: https://blog.reverberate.org/2021/12/18/thread-safety-cpp-rust.html [8]: https://cliffle.com/blog/not-thread-safe [9]: https://web.archive.org/web/20220929143451/https://itsallaboutthebit.com/arc-mutex +[10]: https://blog.dureuill.net/articles/too-dangerous-cpp diff --git a/1_concepts/1_9_phantom/Cargo.toml b/1_concepts/1_9_phantom/Cargo.toml index 6e809d30..ca2c997e 100644 --- a/1_concepts/1_9_phantom/Cargo.toml +++ b/1_concepts/1_9_phantom/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1_9" +name = "task_1_9" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/1_9_phantom/README.md b/1_concepts/1_9_phantom/README.md index fc1f01d7..2a2d85ca 100644 --- a/1_concepts/1_9_phantom/README.md +++ b/1_concepts/1_9_phantom/README.md @@ -1,4 +1,4 @@ -Step 1.9: Phantom types +Task 1.9: Phantom types ======================= Because [Rust] has a rich type system, a programming logic and semantics are mostly expressed in types rather than in data/values, which is known as a "programming with types" concept. Often, this leads to situations where you need to express some type relations without having any values of those types. Here is where [phantom types][5] come in: they carry some semantics on type level, which invariants are checked by compiler, and are totally compiled out in runtime. @@ -89,6 +89,7 @@ For better understanding [`PhantomData`] purpose, design, limitations and use ca - [Rustonomicon: 3.10. PhantomData][2] - [Reddit: Why PhantomData][3] - [RIP Tutorial: Using PhantomData as a Type Marker][4] +- [Aayushya Vajpayee: Write Cleaner, More Maintainable Rust Code with PhantomData][11] - [Sergey Potapov: Phantom Types in Rust][6] @@ -208,3 +209,4 @@ After completing everything above, you should be able to answer (and understand [8]: https://docs.rs/variance/0.1.3/src/variance/lib.rs.html#16 [9]: https://docs.rs/variance/0.1.3/src/variance/lib.rs.html#92 [10]: https://manishearth.github.io/blog/2017/01/11/rust-tidbits-what-is-a-lang-item +[11]: https://aayushyavajpayee.substack.com/p/coming-soon diff --git a/1_concepts/Cargo.toml b/1_concepts/Cargo.toml index 242ac071..5b1f13d3 100644 --- a/1_concepts/Cargo.toml +++ b/1_concepts/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_1" +name = "task_1" version = "0.1.0" edition = "2021" publish = false diff --git a/1_concepts/README.md b/1_concepts/README.md index 2bec4e4b..4fd76495 100644 --- a/1_concepts/README.md +++ b/1_concepts/README.md @@ -1,9 +1,9 @@ -Step 1: Concepts +Chapter 1: Concepts ================ -These steps describe common and necessary-to-know concepts for everyday programming in [Rust]. +These tasks describe common and necessary-to-know concepts for everyday programming in [Rust]. -> ❗️Before completing this step you should complete all its sub-steps. +> ❗️Before completing this task you should complete all its sub-tasks. After doing them you should be able to answer the following questions: - How do I recognize that data is allocated at the heap rather than at the stack? When data should be allocated at the heap? diff --git a/2_idioms/2_1_type_safety/Cargo.toml b/2_idioms/2_1_type_safety/Cargo.toml index df313b2b..4c1b87cd 100644 --- a/2_idioms/2_1_type_safety/Cargo.toml +++ b/2_idioms/2_1_type_safety/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2_1" +name = "task_2_1" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/2_1_type_safety/README.md b/2_idioms/2_1_type_safety/README.md index bb2f891f..b923a739 100644 --- a/2_idioms/2_1_type_safety/README.md +++ b/2_idioms/2_1_type_safety/README.md @@ -1,4 +1,4 @@ -Step 2.1: Rich types ensure correctness +Task 2.1: Rich types ensure correctness ======================================= [Rust] has a rich type system which allows to express our program primitives, entities, notions, logic and semantics mostly in types, rather than in data/values, which is known as a "programming with types" concept. The benefits of this are obvious: the more compiler knows about our problem - the more false programs it will decline. Or, rephrased: __the more we describe about the program in types - the more we reduce the probability for the program to be incorrect__. diff --git a/2_idioms/2_2_mem_replace/Cargo.toml b/2_idioms/2_2_mem_replace/Cargo.toml index 4e8d3fc4..a4d2df7f 100644 --- a/2_idioms/2_2_mem_replace/Cargo.toml +++ b/2_idioms/2_2_mem_replace/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2_2" +name = "task_2_2" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/2_2_mem_replace/README.md b/2_idioms/2_2_mem_replace/README.md index f501d6ee..d88a9132 100644 --- a/2_idioms/2_2_mem_replace/README.md +++ b/2_idioms/2_2_mem_replace/README.md @@ -1,4 +1,4 @@ -Step 2.2: Swapping values with `mem::replace` +Task 2.2: Swapping values with `mem::replace` ============================================= As [Rust] implies [move semantics][1] by default and quite strict [borrowing rules][2], often, there are situations (especially, with large `struct`s and `enum`s) where mutating value in-place or values swapping may not be allowed by borrow checker, which is quite confusing and leads to doing needless clones (so providing redudant performance costs). For example: @@ -27,6 +27,7 @@ For better understanding [`mem::replace`], [`mem::swap`] and [`mem::take`] purpo - [Official `mem::swap` docs][`mem::swap`] - [Official `mem::take` docs][`mem::take`] - [Karol Kuczmarski: Moving out of a container in Rust][4] +- [Ferrous Systems: Using `mem::take` to reduce heap allocations][6] Some examples of useful applying these functions are described below. @@ -141,7 +142,7 @@ __Estimated time__: 1 day -Improve and optimize the code contained in [this step's crate](src/main.rs) to cut off redudant performance costs. +Improve and optimize the code contained in [this task's crate](src/main.rs) to cut off redudant performance costs. Add tests. @@ -165,3 +166,4 @@ After completing everything above, you should be able to answer (and understand [3]: https://rust-unofficial.github.io/patterns/idioms/mem-replace.html [4]: http://xion.io/post/code/rust-move-out-of-container.html [5]: https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html +[6]: https://ferrous-systems.com/blog/rustls-borrow-checker-p1 diff --git a/2_idioms/2_3_bound_impl/Cargo.toml b/2_idioms/2_3_bound_impl/Cargo.toml index f21cdd36..2ed116db 100644 --- a/2_idioms/2_3_bound_impl/Cargo.toml +++ b/2_idioms/2_3_bound_impl/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2_3" +name = "task_2_3" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/2_3_bound_impl/README.md b/2_idioms/2_3_bound_impl/README.md index 5cd1d70a..559da3b0 100644 --- a/2_idioms/2_3_bound_impl/README.md +++ b/2_idioms/2_3_bound_impl/README.md @@ -1,4 +1,4 @@ -Step 2.3: Bound behavior, not data +Task 2.3: Bound behavior, not data ================================== Often, when we want to abstract over some type or behavior in [Rust] we are going from this: @@ -106,7 +106,7 @@ __Estimated time__: 1 day -Refactor the code contained in [this step's crate](src/main.rs) to reduce trait bounds pollution as much as possible. +Refactor the code contained in [this task's crate](src/main.rs) to reduce trait bounds pollution as much as possible. diff --git a/2_idioms/2_4_generic_in_type_out/Cargo.toml b/2_idioms/2_4_generic_in_type_out/Cargo.toml index 59eca185..d161da3d 100644 --- a/2_idioms/2_4_generic_in_type_out/Cargo.toml +++ b/2_idioms/2_4_generic_in_type_out/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2_4" +name = "task_2_4" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/2_4_generic_in_type_out/README.md b/2_idioms/2_4_generic_in_type_out/README.md index f85d9179..40f64aae 100644 --- a/2_idioms/2_4_generic_in_type_out/README.md +++ b/2_idioms/2_4_generic_in_type_out/README.md @@ -1,4 +1,4 @@ -Step 2.4: Abstract type in, concrete type out +Task 2.4: Abstract type in, concrete type out ============================================= @@ -74,7 +74,7 @@ just_print_stringy(&nickname); This is one of the key features, which drive [Rust] expressiveness and ergonomics. Just look over `std` library to see how widely it's used: [`Iterator::eq()`][1], [`Vec::drain()`][2], [`HashMap::extend()`][3], etc. -The downside of this idiom is that compiler generates more code due to monomorphization, so potentially leads to code bloating. The way it can be optimized has already been [explained in "Reducing code bloat optimization" section of 1.6 step][6]. +The downside of this idiom is that compiler generates more code due to monomorphization, so potentially leads to code bloating. The way it can be optimized has already been [explained in "Reducing code bloat optimization" section of 1.6 task][6]. Further reading on theme: - [Joe Wilm: From &str to Cow][4] @@ -102,7 +102,7 @@ __Estimated time__: 1 day -Refactor the code contained in [this step's crate](src/main.rs) to make it more efficient, idiomatic, simple and pleasant to use. +Refactor the code contained in [this task's crate](src/main.rs) to make it more efficient, idiomatic, simple and pleasant to use. diff --git a/2_idioms/2_5_exhaustivity/Cargo.toml b/2_idioms/2_5_exhaustivity/Cargo.toml index c01586b1..082752ff 100644 --- a/2_idioms/2_5_exhaustivity/Cargo.toml +++ b/2_idioms/2_5_exhaustivity/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2_5" +name = "task_2_5" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/2_5_exhaustivity/README.md b/2_idioms/2_5_exhaustivity/README.md index 495b946b..84b99e4e 100644 --- a/2_idioms/2_5_exhaustivity/README.md +++ b/2_idioms/2_5_exhaustivity/README.md @@ -1,4 +1,4 @@ -Step 2.5: Exhaustivity +Task 2.5: Exhaustivity ====================== Exhaustiveness checking in [pattern matching][1] is a very useful tool, allowing to spot certain bugs at compile-time by cheking whether all the combinations of some values where covered and considered in a source code. Being applied correctly, it increases the [fearless refactoring][2] quality of a source code, eliminating possibilities for "forgot to change" bugs to subtly sneak into the codebase whenever it's extended. @@ -160,7 +160,7 @@ __Estimated time__: 1 day -Refactor the code contained in [this step's crate](src/lib.rs), so the bugs introduced there will be uncovered at compile-time, and fix them appropriately. +Refactor the code contained in [this task's crate](src/lib.rs), so the bugs introduced there will be uncovered at compile-time, and fix them appropriately. diff --git a/2_idioms/2_6_sealing/Cargo.toml b/2_idioms/2_6_sealing/Cargo.toml index 215364a3..78d015c7 100644 --- a/2_idioms/2_6_sealing/Cargo.toml +++ b/2_idioms/2_6_sealing/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2_6" +name = "task_2_6" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/2_6_sealing/README.md b/2_idioms/2_6_sealing/README.md index 87b27bd2..5b294eb6 100644 --- a/2_idioms/2_6_sealing/README.md +++ b/2_idioms/2_6_sealing/README.md @@ -1,4 +1,4 @@ -Step 2.6: Sealing +Task 2.6: Sealing ================= Sealing, in programming, usually means that some API (mostly public) cannot be inherited, extended or implemented outside its definition place. For example, a [sealed class or interface in Kotlin][1] cannot be inherited or implemented outside the library where it's defined. In [Rust], this idiom may be applied to [traits][2]. @@ -70,7 +70,7 @@ __Estimated time__: 1 day -Seal the traits defined in [this step's crate](src/lib.rs) in the following way: +Seal the traits defined in [this task's crate](src/lib.rs) in the following way: - Make the [`MyIteratorExt` trait](src/my_iterator_ext.rs) fully sealed. Do it manually, using the [`sealed`] crate or a similar one is __not allowed__. - Make the [`MyError` trait](src/my_error.rs) partially sealed. Only seal the method marked with `#[doc(hidden)]` attribute. - Sealing should work on both module level (disallowing to implement the sealed trait or the sealed method in the root module of the crate or any other module outside the one where the traits are defined, prove it by providing commented implementations in the root module of the crate, which doesn't compile due to the seal, if uncommented) and crate level (prove it by creating [documentation tests which doesn't compile][12] due to the seal). diff --git a/2_idioms/2_6_sealing/src/my_error.rs b/2_idioms/2_6_sealing/src/my_error.rs index 8a7f38f8..055ba0b5 100644 --- a/2_idioms/2_6_sealing/src/my_error.rs +++ b/2_idioms/2_6_sealing/src/my_error.rs @@ -15,7 +15,7 @@ pub trait MyError: Debug + Display { /// ```rust /// use std::fmt; /// - /// use step_2_6::MyError; + /// use task_2_6::MyError; /// /// #[derive(Debug)] /// struct SuperError { diff --git a/2_idioms/2_6_sealing/src/my_iterator_ext.rs b/2_idioms/2_6_sealing/src/my_iterator_ext.rs index 30b12cee..fb022cc5 100644 --- a/2_idioms/2_6_sealing/src/my_iterator_ext.rs +++ b/2_idioms/2_6_sealing/src/my_iterator_ext.rs @@ -18,7 +18,7 @@ pub trait MyIteratorExt: Iterator { /// **Panics** if the formatter helper is formatted more than once. /// /// ```rust - /// use step_2_6::MyIteratorExt as _; + /// use task_2_6::MyIteratorExt as _; /// /// let data = [1.1, 2.71828, -3.]; /// assert_eq!( @@ -46,7 +46,7 @@ pub trait MyIteratorExt: Iterator { /// **Panics** if the formatter helper is formatted more than once. /// /// ```rust - /// use step_2_6::MyIteratorExt as _; + /// use task_2_6::MyIteratorExt as _; /// /// let data = [1.1, 2.71828, -3.]; /// let data_formatter = data.iter().format_with(", ", |elt, f| f(&format_args!("{:.2}", elt))); diff --git a/2_idioms/Cargo.toml b/2_idioms/Cargo.toml index 371362a9..005c5297 100644 --- a/2_idioms/Cargo.toml +++ b/2_idioms/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_2" +name = "task_2" version = "0.1.0" edition = "2021" publish = false diff --git a/2_idioms/README.md b/2_idioms/README.md index 248f80ff..b2d700df 100644 --- a/2_idioms/README.md +++ b/2_idioms/README.md @@ -1,9 +1,9 @@ -Step 2: Idioms +Chapter 2: Idioms ============== -These steps describe common idioms required for writing well-designed and idiomatic [Rust] code. +These tasks describe common idioms required for writing well-designed and idiomatic [Rust] code. -> ❗️Before completing this step you should complete all its sub-steps. +> ❗️Before completing this task you should complete all its sub-tasks. After doing them you should be able to answer the following questions: - Why should I care about types and expressing things in types? How do types help to increase guarantees of a program being correct? diff --git a/3_ecosystem/3_10_threads/Cargo.toml b/3_ecosystem/3_10_threads/Cargo.toml index 96d821ba..3e772a33 100644 --- a/3_ecosystem/3_10_threads/Cargo.toml +++ b/3_ecosystem/3_10_threads/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_10" +name = "task_3_10" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_10_threads/README.md b/3_ecosystem/3_10_threads/README.md index d75324ea..a37e4fb5 100644 --- a/3_ecosystem/3_10_threads/README.md +++ b/3_ecosystem/3_10_threads/README.md @@ -1,4 +1,4 @@ -Step 3.10: Multithreading and parallelism +Task 3.10: Multithreading and parallelism ========================================= One of main [Rust]'s design goals is a [concurrency][1]. [Rust] has a [strong opinion][2] about that, while allows different concurrent models to coexist. @@ -49,6 +49,7 @@ For better understanding and familiarity with [Rust] synchronization primitives - [Aleksey Kladov: Mutexes Are Faster Than Spinlocks][27] - [Mara Bos: Comparing Rust's and C++'s Concurrency Library][31] - [Mahmoud Al-Qudsi: Implementing truly safe semaphores in rust][32] +- [Michael Snoyman: My Best and Worst Deadlock in Rust][35] @@ -93,7 +94,7 @@ Multiprocessing is a system that has more than one or two processors. In Multipr | Creation | The creation of a process is slow and resource-specific. | The creation of a thread is economical in time and resource. | | Classification | Multiprocessing can be symmetric or asymmetric. | Multithreading is not classified. | | Memory | Multiprocessing allocates separate memory and resources for each process or program. | Multithreading threads belonging to the same process share the same memory and resources as that of the process. | -| Pickling objects | Multithreading avoids pickling. | Multiprocessing relies on pickling objects in memory to send to other processes. | +| Pickling objects | Multiprocessing relies on pickling objects in memory to send to other processes. | Multithreading avoids pickling. | | Program | Multiprocessing system allows executing multiple programs and tasks. | Multithreading system executes multiple threads of the same or different processes. | @@ -168,3 +169,4 @@ After completing everything above, you should be able to answer (and understand [32]: https://neosmart.net/blog/implementing-truly-safe-semaphores-in-rust/ [33]: https://vgatherps.github.io/2022-11-28-dec [34]: https://blog.logrocket.com/implementing-data-parallelism-rayon-rust +[35]: https://www.snoyman.com/blog/2024/01/best-worst-deadlock-rust diff --git a/3_ecosystem/3_11_async/Cargo.toml b/3_ecosystem/3_11_async/Cargo.toml index 47857b3e..c655954d 100644 --- a/3_ecosystem/3_11_async/Cargo.toml +++ b/3_ecosystem/3_11_async/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_11" +name = "task_3_11" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_11_async/README.md b/3_ecosystem/3_11_async/README.md index 1036db90..d4ebf6a1 100644 --- a/3_ecosystem/3_11_async/README.md +++ b/3_ecosystem/3_11_async/README.md @@ -1,4 +1,4 @@ -Step 3.11: Async I/O, futures and actors +Task 3.11: Async I/O, futures and actors ======================================== While [threads](../3_10_threads) represent a solution for [CPU-bound] problems, for [I/O-bound] problems, traditionally, the solution is [async (non-blocking) I/O][1]. @@ -72,6 +72,8 @@ For better understanding [`Waker`] design, usage, and features, read through the - [Amos: Understanding Rust futures by going way too deep][25] - [Hayden Stainsby: how I finally understood async/await in Rust (part 4)][67] - [Saoirse Shipwreckt: Why async Rust?][69] +- [Saoirse Shipwreckt: Let futures be futures][70] +- [Saoirse Shipwreckt: FuturesUnordered and the order of futures][71] @@ -184,7 +186,7 @@ __Estimated time__: 2 days Implement an async-driven [CLI] tool, which downloads specified web pages: ```bash -cargo run -p step_3_11 -- [--max-threads=] +cargo run -p task_3_11 -- [--max-threads=] ``` It must read a list of links from the ``, and then concurrently download a content of each link into a separate `.html` file (named by a link). @@ -324,3 +326,5 @@ After completing everything above, you should be able to answer (and understand [67]: https://hegdenu.net/posts/understanding-async-await-4 [68]: https://without.boats/blog/thread-per-core [69]: https://without.boats/blog/why-async-rust +[70]: https://without.boats/blog/let-futures-be-futures +[71]: https://without.boats/blog/futures-unordered diff --git a/3_ecosystem/3_1_testing/Cargo.toml b/3_ecosystem/3_1_testing/Cargo.toml index 7e642a00..fa68c3a9 100644 --- a/3_ecosystem/3_1_testing/Cargo.toml +++ b/3_ecosystem/3_1_testing/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_1" +name = "task_3_1" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_1_testing/README.md b/3_ecosystem/3_1_testing/README.md index f5a7d603..45cd91b4 100644 --- a/3_ecosystem/3_1_testing/README.md +++ b/3_ecosystem/3_1_testing/README.md @@ -1,4 +1,4 @@ -Step 3.1: Testing and mocking +Task 3.1: Testing and mocking ============================= [Rust] testing ecosystem [is not huge, but has grown quite well][1], providing some interesting libraries and solutions. @@ -115,7 +115,7 @@ For better understanding and familiarity with [fuzzing][31] in [Rust], read thro ## More reading - [Aleksey Kladov: How to Test][63] - +- [Joshua Mo: Everything you need to know about testing in Rust][64] ## Integrated tests @@ -132,7 +132,6 @@ For better understanding and familiarity with [fuzzing][31] in [Rust], read thro - [one more example](https://out-of-cheese-error.netlify.app/the-way) - ## Task __Estimated time__: 1 day @@ -140,7 +139,7 @@ __Estimated time__: 1 day -For the implementation of a small [guessing game][51] in [this step's crate](src/main.rs) provide all possible tests you're able to write. +For the implementation of a small [guessing game][51] in [this task's crate](src/main.rs) provide all possible tests you're able to write. @@ -195,3 +194,4 @@ After completing everything above, you should be able to answer (and understand [61]: https://www.youtube.com/watch?v=VDfX44fZoMc [62]: https://nexte.st/ [63]: https://matklad.github.io/2021/05/31/how-to-test.html +[64]: https://www.shuttle.rs/blog/2024/03/21/testing-in-rust diff --git a/3_ecosystem/3_2_macro/Cargo.toml b/3_ecosystem/3_2_macro/Cargo.toml index 021efcec..c0e1631f 100644 --- a/3_ecosystem/3_2_macro/Cargo.toml +++ b/3_ecosystem/3_2_macro/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_2" +name = "task_3_2" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_2_macro/README.md b/3_ecosystem/3_2_macro/README.md index 05f282be..aaa613cc 100644 --- a/3_ecosystem/3_2_macro/README.md +++ b/3_ecosystem/3_2_macro/README.md @@ -1,4 +1,4 @@ -Step 3.2: Declarative and procedural macros +Task 3.2: Declarative and procedural macros =========================================== [Rust] provides strong and convenient built-in capabilities for code generation in a form of [macros][1]. @@ -40,6 +40,7 @@ For better understanding declarative macros design, concepts, usage and features - [Rust By Example: 16. macro_rules!][14] - [The Little Book of Rust Macros][15] - [Rust Reference: 3.1. Macros By Example][16] +- [Aurorans Solis: macros_rule!][18] @@ -164,6 +165,7 @@ After completing everything above, you should be able to answer (and understand [15]: https://danielkeep.github.io/tlborm/book/README.html [16]: https://doc.rust-lang.org/reference/macros-by-example.html [17]: https://doc.rust-lang.org/rust-by-example/macros/variadics.html +[18]: https://auroranssolis.github.io/rust/2024/02/14/macros-rule.html [22]: https://rust-lang.github.io/api-guidelines/macros.html#item-macros-work-anywhere-that-items-are-allowed-c-anywhere [23]: https://doc.rust-lang.org/book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes [25]: https://doc.rust-lang.org/reference/attributes.html diff --git a/3_ecosystem/3_3_date_time/Cargo.toml b/3_ecosystem/3_3_date_time/Cargo.toml index 4b970273..2483160e 100644 --- a/3_ecosystem/3_3_date_time/Cargo.toml +++ b/3_ecosystem/3_3_date_time/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_3" +name = "task_3_3" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_3_date_time/README.md b/3_ecosystem/3_3_date_time/README.md index e4ea1cd5..893b46bf 100644 --- a/3_ecosystem/3_3_date_time/README.md +++ b/3_ecosystem/3_3_date_time/README.md @@ -1,4 +1,4 @@ -Step 3.3: Date and time +Task 3.3: Date and time ======================= [Rust] has a simple [`std::time`] module which contains very basic primitives for time measurements. To operate with dates, time zones, epochs, and other related stuff, the [`time`] and [`chrono`] crates are used in [Rust] ecosystem. @@ -30,7 +30,7 @@ __Estimated time__: 1 day -Provide implementations for `User::age()` and `User::is_adult()` methods in [this step's crate](src/main.rs). +Provide implementations for `User::age()` and `User::is_adult()` methods in [this task's crate](src/main.rs). Prove your implementation correctness with additional tests. For tests reproducibility consider that "now time" is the date specified in the `NOW` constant. diff --git a/3_ecosystem/3_4_regex_parsing/Cargo.toml b/3_ecosystem/3_4_regex_parsing/Cargo.toml index 7c5d9f3a..e9aa0762 100644 --- a/3_ecosystem/3_4_regex_parsing/Cargo.toml +++ b/3_ecosystem/3_4_regex_parsing/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_4" +name = "task_3_4" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_4_regex_parsing/README.md b/3_ecosystem/3_4_regex_parsing/README.md index cfc6f838..35f50025 100644 --- a/3_ecosystem/3_4_regex_parsing/README.md +++ b/3_ecosystem/3_4_regex_parsing/README.md @@ -1,4 +1,4 @@ -Step 3.4: Regular expressions and custom parsers +Task 3.4: Regular expressions and custom parsers ================================================ diff --git a/3_ecosystem/3_5_collections/Cargo.toml b/3_ecosystem/3_5_collections/Cargo.toml index 5729d84d..f47b7962 100644 --- a/3_ecosystem/3_5_collections/Cargo.toml +++ b/3_ecosystem/3_5_collections/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_5" +name = "task_3_5" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_5_collections/README.md b/3_ecosystem/3_5_collections/README.md index 7f7ed6bb..f6e2d065 100644 --- a/3_ecosystem/3_5_collections/README.md +++ b/3_ecosystem/3_5_collections/README.md @@ -1,4 +1,4 @@ -Step 3.5: Collections and iterators +Task 3.5: Collections and iterators =================================== diff --git a/3_ecosystem/3_6_serde/Cargo.toml b/3_ecosystem/3_6_serde/Cargo.toml index 0329ff47..a89d84ac 100644 --- a/3_ecosystem/3_6_serde/Cargo.toml +++ b/3_ecosystem/3_6_serde/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_6" +name = "task_3_6" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_6_serde/README.md b/3_ecosystem/3_6_serde/README.md index 2c5c6619..b0427ae3 100644 --- a/3_ecosystem/3_6_serde/README.md +++ b/3_ecosystem/3_6_serde/README.md @@ -1,4 +1,4 @@ -Step 3.6: Serialization and deserialization +Task 3.6: Serialization and deserialization =========================================== @@ -105,6 +105,7 @@ However, the __main "killer feature"__ of [`musli`] is its __ability to serializ For better understanding and familiarity with [`musli`]'s design, concepts, usage, and features, read through the following articles: - [Official `musli` crate docs][`musli`] +- [John-John Tedro: A fresh look on incremental zero copy serialization][23] @@ -180,5 +181,6 @@ After completing everything above, you should be able to answer (and understand [14]: https://manishearth.github.io/blog/2022/08/03/zero-copy-3-so-zero-its-dot-dot-dot-negative [21]: https://docs.rs/serde/latest/serde/trait.Deserializer.html#tymethod.deserialize_seq [22]: https://docs.rs/musli#modes +[23]: https://udoprog.github.io/rust/2023-10-19/musli-zerocopy.html [30]: https://rkyv.org/rkyv.html [31]: https://rkyv.org/zero-copy-deserialization.html diff --git a/3_ecosystem/3_7_rand_crypto/Cargo.toml b/3_ecosystem/3_7_rand_crypto/Cargo.toml index 70b5299f..4f52b05e 100644 --- a/3_ecosystem/3_7_rand_crypto/Cargo.toml +++ b/3_ecosystem/3_7_rand_crypto/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_7" +name = "task_3_7" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_7_rand_crypto/README.md b/3_ecosystem/3_7_rand_crypto/README.md index 07887468..2c918ca3 100644 --- a/3_ecosystem/3_7_rand_crypto/README.md +++ b/3_ecosystem/3_7_rand_crypto/README.md @@ -1,4 +1,4 @@ -Step 3.7: Randomness and cryptography +Task 3.7: Randomness and cryptography ===================================== diff --git a/3_ecosystem/3_8_log/Cargo.toml b/3_ecosystem/3_8_log/Cargo.toml index b6e5b7be..25b037b7 100644 --- a/3_ecosystem/3_8_log/Cargo.toml +++ b/3_ecosystem/3_8_log/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_8" +name = "task_3_8" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_8_log/README.md b/3_ecosystem/3_8_log/README.md index 51bb32b8..40883011 100644 --- a/3_ecosystem/3_8_log/README.md +++ b/3_ecosystem/3_8_log/README.md @@ -1,4 +1,4 @@ -Step 3.8: Logging and tracing +Task 3.8: Logging and tracing ============================= [Rust] has flexible type system and [metaprogramming][1] capabilities, allowing to build both efficient and highly reusable log system. The idea is very similar to [`serde`] and is introduced in a widely used [`log`], [`slog`] and [`tracing`] crates. @@ -49,8 +49,10 @@ Speaking of [tracing][10], the [`tracing`] crate has good integrations with [Ope For better understanding and familiarity with [`tracing`]'s design, concepts, usage, and features, read through the following articles: - [Official `tracing` crate docs][`tracing`] +- [Joshua Mo: Getting Started with Tracing in Rust][13] - [Yoav Danieli: Guide to OpenTelemetry Distributed Tracing in Rust][11] -- [Tokio Blog: Diagnostics with Tracing][13] +- [Tokio Blog: Diagnostics with Tracing][14] +- [Hayden Stainsby: debugging tokio instrumentation][15] @@ -113,4 +115,6 @@ After completing everything above, you should be able to answer (and understand [10]: https://en.wikipedia.org/wiki/Tracing_(software) [11]: https://www.aspecto.io/blog/distributed-tracing-with-opentelemetry-rust [12]: https://www.thecodedmessage.com/posts/logging -[13]: https://tokio.rs/blog/2019-08-tracing +[13]: https://www.shuttle.rs/blog/2024/01/09/getting-started-tracing-rust +[14]: https://tokio.rs/blog/2019-08-tracing +[15]: https://hegdenu.net/posts/debugging-tokio-instrumentation diff --git a/3_ecosystem/3_9_cmd_env_conf/Cargo.toml b/3_ecosystem/3_9_cmd_env_conf/Cargo.toml index d9cb175e..ecd813c5 100644 --- a/3_ecosystem/3_9_cmd_env_conf/Cargo.toml +++ b/3_ecosystem/3_9_cmd_env_conf/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3_9" +name = "task_3_9" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/3_9_cmd_env_conf/README.md b/3_ecosystem/3_9_cmd_env_conf/README.md index 18861cc7..ee2be9f8 100644 --- a/3_ecosystem/3_9_cmd_env_conf/README.md +++ b/3_ecosystem/3_9_cmd_env_conf/README.md @@ -1,4 +1,4 @@ -Step 3.9: Command-line arguments, environment variables and configs +Task 3.9: Command-line arguments, environment variables and configs =================================================================== @@ -80,19 +80,15 @@ The following priority should be applied (in ascending order) when merging: [CLI] of the program should look like: ``` $ cargo run -- --help -step_3_9 0.1.0 -Prints its configuration to STDOUT. +Prints its configuration to STDOUT -USAGE: - step_3_9 [FLAGS] [OPTIONS] +Usage: task_3_9 [OPTIONS] -FLAGS: - -d, --debug Enables debug mode - -h, --help Prints help information - -V, --version Prints version information - -OPTIONS: - -c, --conf Path to configuration file [env: CONF_FILE=] [default: config.toml] +Options: + -d, --debug Enables debug mode + -c, --conf Path to configuration file [env: CONF_FILE=] [default: config.toml] + -h, --help Print help + -V, --version Print version ``` diff --git a/3_ecosystem/Cargo.toml b/3_ecosystem/Cargo.toml index c5bc9818..075fe62a 100644 --- a/3_ecosystem/Cargo.toml +++ b/3_ecosystem/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_3" +name = "task_3" version = "0.1.0" edition = "2021" publish = false diff --git a/3_ecosystem/README.md b/3_ecosystem/README.md index 7da97175..60df9c8a 100644 --- a/3_ecosystem/README.md +++ b/3_ecosystem/README.md @@ -1,9 +1,9 @@ -Step 3: Common ecosystem +Chapter 3: Common ecosystem ======================== -These steps describe common crates and tools in [Rust] ecosystem required for application and library development. +These tasks describe common crates and tools in [Rust] ecosystem required for application and library development. -> ❗️Before completing this step you should complete all its sub-steps. +> ❗️Before completing this task you should complete all its sub-tasks. After doing them you should be able to answer the following questions: - What testing capabilities does [Rust] offer and when should I use them? Why should I follow [BDD] style? diff --git a/4_backend/4_1_db/Cargo.toml b/4_backend/4_1_db/Cargo.toml index 834de6fd..141a95e4 100644 --- a/4_backend/4_1_db/Cargo.toml +++ b/4_backend/4_1_db/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_4_1" +name = "task_4_1" version = "0.1.0" edition = "2021" publish = false diff --git a/4_backend/4_1_db/README.md b/4_backend/4_1_db/README.md index 7cd410c1..cec2cf9c 100644 --- a/4_backend/4_1_db/README.md +++ b/4_backend/4_1_db/README.md @@ -1,4 +1,4 @@ -Step 4.1: Databases, connection pools and ORMs +Task 4.1: Databases, connection pools and ORMs ============================================== The current situation with databases integration in [Rust] ecosystem is illustrated quite well in [this "Awesome Rust" section][1] and in ["Database" topic of "Are we web yet?"][2]: the majority of the drivers are implemented fully in [Rust], and only few wrap existing libraries, and of course, most of them use [async I/O][3]. diff --git a/4_backend/4_2_http/Cargo.toml b/4_backend/4_2_http/Cargo.toml index 226ccc31..be58fb77 100644 --- a/4_backend/4_2_http/Cargo.toml +++ b/4_backend/4_2_http/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_4_2" +name = "task_4_2" version = "0.1.0" edition = "2021" publish = false diff --git a/4_backend/4_2_http/README.md b/4_backend/4_2_http/README.md index 44e10d9b..d991ef31 100644 --- a/4_backend/4_2_http/README.md +++ b/4_backend/4_2_http/README.md @@ -1,4 +1,4 @@ -Step 4.2: HTTP servers and clients +Task 4.2: HTTP servers and clients ================================== The current situation regarding [HTTP] in [Rust] ecosystem can be grasped quite well in [the "Web programming" section of "Awesome Rust"][1] and in the ["Web Frameworks"][2], ["HTTP Clients"][3] and ["Lower Web-Stack" topics of "Are we web yet?"][4]. Of course, most of them use [async I/O][5]. @@ -97,7 +97,7 @@ __Estimated time__: 1 day -Rework [the task from the previous step](../4_1_db/README.md#task) in a [client-server architecture][51]. It should consist of a [CLI] client and a server [daemon][52], and utilize the ["thin client" approach][53]: +Rework [the task from the previous task](../4_1_db/README.md#task) in a [client-server architecture][51]. It should consist of a [CLI] client and a server [daemon][52], and utilize the ["thin client" approach][53]: - [CLI] client does nothing except sending commands "as is" to the server and rendering its responses. - Server [daemon][52], having a single [HTTP] endpoint, does all the parsing and executing of commands sent by the [CLI] client. diff --git a/4_backend/4_3_api/Cargo.toml b/4_backend/4_3_api/Cargo.toml index 38c16fba..65374d9c 100644 --- a/4_backend/4_3_api/Cargo.toml +++ b/4_backend/4_3_api/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_4_3" +name = "task_4_3" version = "0.1.0" edition = "2021" publish = false diff --git a/4_backend/4_3_api/README.md b/4_backend/4_3_api/README.md index 62cd9db2..64ff5fbf 100644 --- a/4_backend/4_3_api/README.md +++ b/4_backend/4_3_api/README.md @@ -1,4 +1,4 @@ -Step 4.3: API servers, clients and tools +Task 4.3: API servers, clients and tools ======================================== Naturally, in [client-server][4] applications, a client and a server negotiate with each other via some [API (application programming interface)][API], which often takes form of [RPC (remote procedure call)][RPC] for better structuring and standardizing (due [IDL (interface definition language)][IDL] usage). @@ -26,7 +26,7 @@ For more information about [REST], read through the following articles: > > An OpenAPI definition can then be used by documentation generation tools to display the API, code generation tools to generate servers and clients in various programming languages, testing tools, and many other use cases. -In [Rust] ecosystem, most [OpenAPI] crates follow the __code-first approach__ (generating [OpenAPI] schema from source code). The most notable crates for this are [`utoipa`] and [`okapi`]. +In [Rust] ecosystem, most [OpenAPI] crates follow the __code-first approach__ (generating [OpenAPI] schema from source code). The most notable crates for this are [`utoipa`], [`okapi`] and [`apistos`]. For the opposite (generating source code from [OpenAPI] schema) [Rust] ecosystem lacks its own pure implementation, and the original [OpenAPI] tool [`openapi-generator`] should be used (powered by the [`swagger`] crate). @@ -35,8 +35,11 @@ For more familiarity with [OpenAPI] and using it in [Rust], read through the fol - [SwaggerHub Documentation: OpenAPI 3.0 Tutorial][122] - [Official `utoipa` crate docs][`cynic`] - [Official `okapi` crate docs][`okapi`] +- [Official `apistos` crate docs][`apistos`] - [Twilio Docs: Generate a Rust client for Twilio's API][121] - [Fabian Odenthal: Auto-Generating & Validating OpenAPI Docs in Rust: A Streamlined Approach with Utoipa and Schemathesis][123] +- [Olly Dixon: Auto-generating API service using Rust, to TypeScript & Dart][124] +- [Joshua Mo: Working with OpenAPI using Rust][125] @@ -84,24 +87,7 @@ For more familiarity with making [GraphQL] requests in [Rust], read through the -## gRPC -[gRPC] is a widely-adopted high performance [RPC] framework, having a __strict schema__, powered with pluggable support for load balancing, tracing, health checking and authentication, built on top of [HTTP/2] (and so, having a __mandatory encryption__), and __heavily using code-from-schema generation__. - -For more familiarity with [gRPC], read through the following articles: -- [gRPC docs: Introduction to gRPC][301] -- [gRPC docs: Core concepts, architecture and lifecycle][302] - - -### Server and client - -For implementing a [gRPC] server in [Rust], there are two main production-ready crates in its ecosystem: [`tonic`] (pure [Rust] implementation, based on [`tokio`]) and [`grpcio`] (wrapper around [gRPC core][311] implementation). - -In [gRPC] ecosystem, usually, implementing a [gRPC] client doesn't differ much from implementing a server, since both are auto-generated from the same `.proto` schema. So, for [Rust], the same [`tonic`] and [`grpcio`] crates do the job when it comes to making [gRPC] requests. - -For more familiarity with using [gRPC] in [Rust], read through the following articles: -- [Official `tonic` crate docs][`tonic`] -- [Official `grpcio` crate docs][`grpcio`] @@ -113,7 +99,7 @@ __Estimated time__: 1 day -Rework [the task from the previous step](../4_2_http/README.md#task) in a ["thick client" paradigm][41]: +Rework [the task from the previous task](../4_2_http/README.md#task) in a ["thick client" paradigm][41]: - Server represents a [REST]ful [API] with separate endpoints for each operation. - [CLI] client parses commands by itself and makes accurate requests to the server [REST]ful [API]. @@ -134,11 +120,11 @@ After completing everything above, you should be able to answer (and understand - What does REST paradigm mean? What are essentials of RESTful API? Which strengths does it have? What does it lack? - What is OpenAPI? What is Swagger? How do they relate? Why are they beneficial for RESTful API? - What is GraphQL? Which are strong sides of this technology? What problems does it bring in practice? -- What is gRPC? What are its strengths? Which are good use-cases for it, and which are not? Why? +[`apistos`]: https://docs.rs/apistos [`async-graphql`]: https://docs.rs/async-graphql [`cynic`]: https://docs.rs/cynic [`graphql-client`]: https://github.com/graphql-rust/graphql-client @@ -181,6 +167,8 @@ After completing everything above, you should be able to answer (and understand [121]: https://www.twilio.com/docs/openapi/generating-a-rust-client-for-twilios-api [122]: https://support.smartbear.com/swaggerhub/docs/tutorials/openapi-3-tutorial.html [123]: https://identeco.de/en/blog/generating_and_validating_openapi_docs_in_rust +[124]: https://www.polydelic.com/media/autogenerating-a-rust-api-to-typescript-and-dart +[125]: https://www.shuttle.rs/blog/2024/04/04/using-openapi-rust [200]: https://graphql.org/learn/queries [201]: https://graphql.org/learn/schema [202]: https://graphql.org/learn/introspection diff --git a/4_backend/4_4_grpc/Cargo.toml b/4_backend/4_4_grpc/Cargo.toml new file mode 100644 index 00000000..1445727a --- /dev/null +++ b/4_backend/4_4_grpc/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "task_4_4" +version = "0.1.0" +edition = "2021" +publish = false diff --git a/4_backend/4_4_grpc/README.md b/4_backend/4_4_grpc/README.md new file mode 100644 index 00000000..c2be9aed --- /dev/null +++ b/4_backend/4_4_grpc/README.md @@ -0,0 +1,55 @@ +Task 4.4: RPC +======================================== + +[gRPC] is a widely-adopted high performance [RPC] framework, having a __strict schema__, powered with pluggable support for load balancing, tracing, health checking and authentication, built on top of [HTTP/2] (and so, having a __mandatory encryption__), and __heavily using code-from-schema generation__. + +For more familiarity with [gRPC], read through the following articles: +- [gRPC docs: Introduction to gRPC][301] +- [gRPC docs: Core concepts, architecture and lifecycle][302] + +### Server and client + +For implementing a [gRPC] server in [Rust], there are two main production-ready crates in its ecosystem: [`tonic`] (pure [Rust] implementation, based on [`tokio`]) and [`grpcio`] (wrapper around [gRPC core][311] implementation). + +In [gRPC] ecosystem, usually, implementing a [gRPC] client doesn't differ much from implementing a server, since both are auto-generated from the same `.proto` schema. So, for [Rust], the same [`tonic`] and [`grpcio`] crates do the job when it comes to making [gRPC] requests. + +For more familiarity with using [gRPC] in [Rust], read through the following articles: +- [Official `tonic` crate docs][`tonic`] +- [Official `grpcio` crate docs][`grpcio`] + +## Task + +__Estimated time__: 1 day + +Rework the application [from the previous task](../4_3_api/README.md#task) by introducing [gRPC] as an [API] between the ["thick client"][41] and the server, while preserving the [REST]ful [API]: + +- Server communicates with the client via [gRPC]. +- [CLI] client parses commands by itself and makes accurate requests to the server via [gRPC]. +- it should be still possible to perform all the operations via [cURL] (or any other [HTTP]/[API] client) directly on the [REST]ful [API] server. + +Try to keep your solution as simple and straightforward as possible. + +## Questions + +After completing everything above, you should be able to answer (and understand why) the following questions: +- What is gRPC? What is the difference between RPC and gRPC? +- What are the strengths of gRPC? Which are good use-cases for it, and which are not? Why? + +[`grpcio`]: https://docs.rs/crate/grpcio +[`tarpc`]: https://docs.rs/tarpc +[`tonic`]: https://docs.rs/tonic +[`tokio`]: https://docs.rs/tokio +[API]: https://en.wikipedia.org/wiki/API +[CLI]: https://en.wikipedia.org/wiki/Command-line_interface +[cURL]: https://en.wikipedia.org/wiki/CURL +[gRPC]: https://grpc.io +[HTTP]: https://en.wikipedia.org/wiki/HTTP +[HTTP/2]: https://en.wikipedia.org/wiki/HTTP/2 +[REST]: https://en.wikipedia.org/wiki/Representational_state_transfer +[RPC]: https://en.wikipedia.org/wiki/Remote_procedure_call +[Rust]: https://www.rust-lang.org + +[301]: https://grpc.io/docs/what-is-grpc/introduction +[302]: https://grpc.io/docs/what-is-grpc/core-concepts +[311]: https://github.com/grpc/grpc +[41]: https://en.wikipedia.org/wiki/Rich_client diff --git a/4_backend/4_4_grpc/src/main.rs b/4_backend/4_4_grpc/src/main.rs new file mode 100644 index 00000000..4722cdbc --- /dev/null +++ b/4_backend/4_4_grpc/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Implement me!"); +} diff --git a/4_backend/Cargo.toml b/4_backend/Cargo.toml index 001c6cfd..b9fa1c72 100644 --- a/4_backend/Cargo.toml +++ b/4_backend/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "step_4" +name = "task_4" version = "0.1.0" edition = "2021" publish = false diff --git a/4_backend/README.md b/4_backend/README.md index c1d2ff78..2a4bc5a4 100644 --- a/4_backend/README.md +++ b/4_backend/README.md @@ -1,9 +1,9 @@ -Step 4: Backend ecosystem +Chapter 4: Backend ecosystem ========================= -These steps describe common crates and tools in [Rust] ecosystem required for web backend development. +These tasks describe common crates and tools in [Rust] ecosystem required for web backend development. -> ❗️Before completing this step you should complete all its sub-steps. +> ❗️Before completing this task you should complete all its sub-tasks. After doing them you should be able to answer the following questions: - How should I interact with databases in [Rust] application and why? How can I organize migrations for my project? diff --git a/5_zero2prod/10_chapter/10_10.md b/5_zero2prod/10_chapter/10_10.md index c3f87576..75e5a345 100644 --- a/5_zero2prod/10_chapter/10_10.md +++ b/5_zero2prod/10_chapter/10_10.md @@ -1,2 +1,3 @@ Secure api of the app from the previous exercises. Create simple sign-up/login rest api which should use email and password for authorization and return jwt tokens. Make other routes available only with a registered jwt token. +**Make sure to update your tests considering the auth.** diff --git a/5_zero2prod/README.md b/5_zero2prod/README.md index 5374ef1c..dfa5d5bf 100644 --- a/5_zero2prod/README.md +++ b/5_zero2prod/README.md @@ -1,9 +1,9 @@ -Step 5: Zero To Production +Chapter 5: Zero To Production ================= -__Estimated time__: 14 days +__Estimated time__: 21 days -These steps contain exercises for the [Zero To Production](https://www.zero2prod.com/index.html) Book. Folders are named after the chapters in the book. Files in these folders are named like that: *chapter*_*subchapter*. The files contain exercises which you should do **after** reading the corresponding subchapter. +These tasks contain exercises for the [Zero To Production](https://www.zero2prod.com/index.html) Book. Folders are named after the chapters in the book. Files in these folders are named like that: *chapter*_*subchapter*. The files contain exercises which you should do **after** reading the corresponding subchapter. ### How to make pull requests diff --git a/6_project/README.md b/6_project/README.md index 532b2ab1..3cdf4872 100644 --- a/6_project/README.md +++ b/6_project/README.md @@ -1,4 +1,4 @@ -Step 6: Capstone project +Chapter 6: Capstone project ========================= Congratulation! You've almost done it! @@ -9,7 +9,7 @@ Create a portfolio project using Rust within a one-week timeframe. The project s > ❗️ Open a PR to the master/main branch so that mentors can leave feedback on your project. -## Step 6.1: Agree on your capstone project +## Task 6.1: Agree on your capstone project Choose a project idea that is suitable for implementation within a one-week timeframe. Consider the complexity and feasibility of the project. @@ -19,16 +19,16 @@ If you're having trouble finding a suitable subject for your project, don't hesi > ❗️ You have to approve the subject of the project with your mentor. -## Step 6.2: Get approvement of basic implementation from the first mentor +## Task 6.2: Get approvement of basic implementation from the first mentor Focus on designing and developing a minimum viable version of your project, rather than a fully finished product, given the limited time frame. Don't worry about achieving perfection in your implementation at this stage. Just ensure you get your mentor's approval on your work. -## Step 6.3: Get 4 reviews from peers and mentors +## Task 6.3: Get 4 reviews from peers and mentors Teamwork is crucial in our program, as is respecting senior team members and acknowledging the strengths of your peers. You are required to obtain four reviews of your work from your peers and mentors. These reviews should incorporate diverse perspectives: at least one should be from a peer and at least one from a mentor outside your immediate group. You're encouraged to consider and apply the majority of the feedback you receive in these reviews. -## Step 6.4: Present your project +## Task 6.4: Present your project In a successful team, members feel comfortable being vulnerable and open to feedback. As such, you are expected to present your project to your peers and mentors. This will allow you to receive more feedback, further facilitating your growth and learning. diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 4a324439..00000000 --- a/Cargo.lock +++ /dev/null @@ -1,135 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "step_1" -version = "0.1.0" - -[[package]] -name = "step_1_1" -version = "0.1.0" - -[[package]] -name = "step_1_2" -version = "0.1.0" - -[[package]] -name = "step_1_3" -version = "0.1.0" - -[[package]] -name = "step_1_4" -version = "0.1.0" - -[[package]] -name = "step_1_5" -version = "0.1.0" - -[[package]] -name = "step_1_6" -version = "0.1.0" - -[[package]] -name = "step_1_7" -version = "0.1.0" - -[[package]] -name = "step_1_8" -version = "0.1.0" - -[[package]] -name = "step_1_9" -version = "0.1.0" - -[[package]] -name = "step_2" -version = "0.1.0" - -[[package]] -name = "step_2_1" -version = "0.1.0" - -[[package]] -name = "step_2_2" -version = "0.1.0" - -[[package]] -name = "step_2_3" -version = "0.1.0" - -[[package]] -name = "step_2_4" -version = "0.1.0" - -[[package]] -name = "step_2_5" -version = "0.1.0" - -[[package]] -name = "step_2_6" -version = "0.1.0" - -[[package]] -name = "step_3" -version = "0.1.0" - -[[package]] -name = "step_3_1" -version = "0.1.0" - -[[package]] -name = "step_3_10" -version = "0.1.0" - -[[package]] -name = "step_3_11" -version = "0.1.0" - -[[package]] -name = "step_3_2" -version = "0.1.0" - -[[package]] -name = "step_3_3" -version = "0.1.0" - -[[package]] -name = "step_3_4" -version = "0.1.0" - -[[package]] -name = "step_3_5" -version = "0.1.0" - -[[package]] -name = "step_3_6" -version = "0.1.0" - -[[package]] -name = "step_3_7" -version = "0.1.0" - -[[package]] -name = "step_3_8" -version = "0.1.0" - -[[package]] -name = "step_3_9" -version = "0.1.0" - -[[package]] -name = "step_4" -version = "0.1.0" - -[[package]] -name = "step_4_1" -version = "0.1.0" - -[[package]] -name = "step_4_2" -version = "0.1.0" - -[[package]] -name = "step_4_3" -version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index a31ded9c..c3ff01b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "1_concepts", "1_concepts/1_*", diff --git a/README.md b/README.md index 52c73d37..3852f057 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ In this rustcamp, you will participate in the [Rustcamp], a rigorous, step-by-st | Description | Number | |---------------------------------|-------:| -| Total applications to Rustcamp | 325 | -| Total number of Participants | 109 | -| Mentors | 29 | -| Certified Professionals | 25 | +| Total applications to Rustcamp | 507 | +| Total number of Participants | 187 | +| Mentors | 38 | +| Certified Professionals | 40 | ## Prerequisites @@ -35,59 +35,96 @@ Please, read [instructions][Getting Started]. Please, read [instructions][Submitting Solutions]. +### Toolchain + +- [rustup] for installing [Rust] toolchain and keeping it up-to-date. +- [CLion]/[IntelliJ IDEA] + [IntelliJ Rust] + [Toml][IntelliJ Toml] plugins as development environment (or any other on your choice). + + +### Bookshelf + +- [Rust Book] teaches and explains [Rust] basics. +- [Rust By Example] teaches you [Rust] basics using editable examples. +- [Rust Reference] is not a formal spec, but is more detailed and comprehensive than the [Rust Book]. +- [Cheats.rs] and [Rust SVG Cheatsheet] for quick reference. +- [Rust Edition Guide] for considering improvements of [Rust 2018] and [Rust 2021]. +- [Rust std lib] documentation. +- [Cargo Book] is a guide to [Cargo], [Rust]'s build tool and dependency manager. +- [Rustdoc Book] is a guide to `rustdoc` documentation tool. +- [Rust Cookbook] is a collection of simple examples that demonstrate good practices to accomplish common programming tasks, using the crates of the [Rust] ecosystem. +- [Rust Design Patterns] is an open source repository of [Rust] design patterns and idioms. +- [Effective Rust] is a collection of guidelines that had been learned from real world experience of creating software in [Rust]. +- [Rust API Guidelines] is a set of recommendations on how to design and present APIs for [Rust]. +- [Rust FAQ] answers common question about [Rust]. +- [Rust Playground] allows to share and check runnable [Rust] code snippets online. +- [Awesome Rust] is a curated list of [Rust] code and resources. +- [This Week in Rust] represents handpicked and subscribable [Rust] weekly updates. +- [Baby Steps] blog of [Nicholas Matsakis](https://github.com/nikomatsakis) shares useful [Rust] patterns, ideas and design decisions. + + + + +### Schedule + +Each task must be performed as a separate [PR (pull request)][PR] with an appropriate name and checkmarked here in README's schedule after completion. Each task is a [Cargo workspace member][13], so you can run/test it from the project root (i.e. `cargo run -p task_1_8`). __Consider to use [rustfmt] and [Clippy] when you're writing [Rust] code.__ + +Each task has the estimated time for completion. If any deeper investigation on task's theme is needed by you, then it's on your own. + +Do not hesitate to ask your mentor/lead with questions, however you won't receive any concrete answer, but rather a direction for your own investigation. _Mentor/Lead is the one who asks questions here, demanding concrete and complete answers._ + ## Curriculum -- [ ] [0. Become familiar with Rust basics][Step 0] (1 week) -- [ ] [1. Concepts][Step 1] (2 weeks) - - [ ] [1.1. Default values, cloning and copying][Step 1.1] - - [ ] [1.2. Boxing and pinning][Step 1.2] - - [ ] [1.3. Shared ownership and interior mutability][Step 1.3] - - [ ] [1.4. Clone-on-write][Step 1.4] - - [ ] [1.5. Conversions, casting and dereferencing][Step 1.5] - - [ ] [1.6. Static and dynamic dispatch][Step 1.6] - - [ ] [1.7. `Sized` and `?Sized` types][Step 1.7] - - [ ] [1.8. Thread safety][Step 1.8] - - [ ] [1.9. Phantom types][Step 1.9] - - [ ] [1.10. Summary Task][Step 1 Summary Task] -- [ ] [2. Idioms][Step 2] (2 weeks) - - [ ] [2.1. Rich types ensure correctness][Step 2.1] - - [ ] [2.2. Swapping values with `mem::replace`][Step 2.2] - - [ ] [2.3. Bound behavior, not data][Step 2.3] - - [ ] [2.4. Abstract type in, concrete type out][Step 2.4] - - [ ] [2.5. Exhaustivity][Step 2.5] - - [ ] [2.6. Sealing][Step 2.6] - - [ ] [2.7. Summary Task][Step 2 Summary Task] -- [ ] [3. Ecosystem][Step 3] (3 weeks) - - [ ] [3.1. Testing and mocking][Step 3.1] - - [ ] [3.2. Declarative and procedural macros][Step 3.2] - - [ ] [3.3. Date and time][Step 3.3] - - [ ] [3.4. Regular expressions and custom parsers][Step 3.4] - - [ ] [3.5. Collections and iterators][Step 3.5] - - [ ] [3.6. Serialization and deserialization][Step 3.6] - - [ ] [3.7. Randomness and cryptography][Step 3.7] - - [ ] [3.8. Logging and tracing][Step 3.8] - - [ ] [3.9. Command-line arguments, environment variables and configs][Step 3.9] - - [ ] [3.10. Multithreading and parallelism][Step 3.10] - - [ ] [3.11. Async I/O, futures and actors][Step 3.11] - - [ ] [3.12. Summary Task][Step 3 Summary Task] -- [ ] [4. Backend ecosystem][Step 4] (2 weeks) - - [ ] [4.1. Databases, connection pools and ORMs][Step 4.1] - - [ ] [4.2. HTTP servers and clients][Step 4.2] - - [ ] [4.3. API servers, clients and tools][Step 4.3] - - [ ] [4.4. Summary Task][Step 4 Summary Task] -- [ ] [Agree your capstone project][Step 6.1] -- [ ] [5. Zero To Production][Step 5] (3 weeks) - - [ ] [5.1. Basic actix-web][Step 5.1] - - [ ] [5.2. Logging][Step 5.2] - - [ ] [5.3. Docker and deployment][Step 5.3] - - [ ] [5.4. Type-Driven Development and testing][Step 5.4] - - [ ] [5.5. Advanced actix-web and error handling][Step 5.5] - - [ ] [5.6. Authorization][Step 5.6] -- [ ] [6. Capstone Project][Step 6] (1 week) - - [ ] [6.1. Agree your capstone project][Step 6.1] - - [ ] [6.2. Get approvement of basic implementation from the first mentor][Step 6.2] - - [ ] [6.3. Get 4 reviews from peers and mentors][Step 6.3] - - [ ] [6.4. Present your project][Step 6.4] +- [ ] [0. Become familiar with Rust basics][Task 0] (1 week) +- [ ] [1. Concepts][Task 1] (2 weeks) + - [ ] [1.1. Default values, cloning and copying][Task 1.1] + - [ ] [1.2. Boxing and pinning][Task 1.2] + - [ ] [1.3. Shared ownership and interior mutability][Task 1.3] + - [ ] [1.4. Clone-on-write][Task 1.4] + - [ ] [1.5. Conversions, casting and dereferencing][Task 1.5] + - [ ] [1.6. Static and dynamic dispatch][Task 1.6] + - [ ] [1.7. `Sized` and `?Sized` types][Task 1.7] + - [ ] [1.8. Thread safety][Task 1.8] + - [ ] [1.9. Phantom types][Task 1.9] + - [ ] [1.10. Summary Task][Task 1 Summary Task] +- [ ] [2. Idioms][Task 2] (2 weeks) + - [ ] [2.1. Rich types ensure correctness][Task 2.1] + - [ ] [2.2. Swapping values with `mem::replace`][Task 2.2] + - [ ] [2.3. Bound behavior, not data][Task 2.3] + - [ ] [2.4. Abstract type in, concrete type out][Task 2.4] + - [ ] [2.5. Exhaustivity][Task 2.5] + - [ ] [2.6. Sealing][Task 2.6] + - [ ] [2.7. Summary Task][Task 2 Summary Task] +- [ ] [3. Ecosystem][Task 3] (3 weeks) + - [ ] [3.1. Testing and mocking][Task 3.1] + - [ ] [3.2. Declarative and procedural macros][Task 3.2] + - [ ] [3.3. Date and time][Task 3.3] + - [ ] [3.4. Regular expressions and custom parsers][Task 3.4] + - [ ] [3.5. Collections and iterators][Task 3.5] + - [ ] [3.6. Serialization and deserialization][Task 3.6] + - [ ] [3.7. Randomness and cryptography][Task 3.7] + - [ ] [3.8. Logging and tracing][Task 3.8] + - [ ] [3.9. Command-line arguments, environment variables and configs][Task 3.9] + - [ ] [3.10. Multithreading and parallelism][Task 3.10] + - [ ] [3.11. Async I/O, futures and actors][Task 3.11] + - [ ] [3.12. Summary Task][Task 3 Summary Task] +- [ ] [4. Backend ecosystem][Task 4] (2 weeks) + - [ ] [4.1. Databases, connection pools and ORMs][Task 4.1] + - [ ] [4.2. HTTP servers and clients][Task 4.2] + - [ ] [4.3. API servers, clients and tools][Task 4.3] + - [ ] [4.4. Summary Task][Task 4 Summary Task] +- [ ] [Agree your capstone project][Task 6.1] +- [ ] [5. Zero To Production][Task 5] (3 weeks) + - [ ] [5.1. Basic actix-web][Task 5.1] + - [ ] [5.2. Logging][Task 5.2] + - [ ] [5.3. Docker and deployment][Task 5.3] + - [ ] [5.4. Type-Driven Development and testing][Task 5.4] + - [ ] [5.5. Advanced actix-web and error handling][Task 5.5] + - [ ] [5.6. Authorization][Task 5.6] +- [ ] [6. Capstone Project][Task 6] (1 week) + - [ ] [6.1. Agree your capstone project][Task 6.1] + - [ ] [6.2. Get approvement of basic implementation from the first mentor][Task 6.2] + - [ ] [6.3. Get 4 reviews from peers and mentors][Task 6.3] + - [ ] [6.4. Present your project][Task 6.4] ## Useful links @@ -113,56 +150,56 @@ Please, read [instructions][Submitting Solutions]. Rustcamp materials were based on the [Rust Incubator](https://github.com/instrumentisto/rust-incubator) program created by the Legendary [Kai](https://github.com/tyranron) 💜 and Member of the Jedi High Council [Luca Palmieri](https://github.com/LukeMathWalker) 🧙‍♂️ -[Step 0]: 0_basics -[Step 1]: 1_concepts -[Step 1.1]: 1_concepts/1_1_default_clone_copy -[Step 1.2]: 1_concepts/1_2_box_pin -[Step 1.3]: 1_concepts/1_3_rc_cell -[Step 1.4]: 1_concepts/1_4_cow -[Step 1.5]: 1_concepts/1_5_convert_cast_deref -[Step 1.6]: 1_concepts/1_6_dispatch -[Step 1.7]: 1_concepts/1_7_sized -[Step 1.8]: 1_concepts/1_8_thread_safety -[Step 1.9]: 1_concepts/1_9_phantom -[Step 1 Summary Task]: 1_concepts/README.md#task -[Step 2]: 2_idioms -[Step 2.1]: 2_idioms/2_1_type_safety -[Step 2.2]: 2_idioms/2_2_mem_replace -[Step 2.3]: 2_idioms/2_3_bound_impl -[Step 2.4]: 2_idioms/2_4_generic_in_type_out -[Step 2.5]: 2_idioms/2_5_exhaustivity -[Step 2.6]: 2_idioms/2_6_sealing -[Step 2 Summary Task]: 2_idioms/README.md#task -[Step 3]: 3_ecosystem -[Step 3.1]: 3_ecosystem/3_1_testing -[Step 3.2]: 3_ecosystem/3_2_macro -[Step 3.3]: 3_ecosystem/3_3_date_time -[Step 3.4]: 3_ecosystem/3_4_regex_parsing -[Step 3.5]: 3_ecosystem/3_5_collections -[Step 3.6]: 3_ecosystem/3_6_serde -[Step 3.7]: 3_ecosystem/3_7_rand_crypto -[Step 3.8]: 3_ecosystem/3_8_log -[Step 3.9]: 3_ecosystem/3_9_cmd_env_conf -[Step 3.10]: 3_ecosystem/3_10_threads -[Step 3.11]: 3_ecosystem/3_11_async -[Step 3 Summary Task]: 3_ecosystem/README.md#task -[Step 4]: 4_backend -[Step 4.1]: 4_backend/4_1_db -[Step 4.2]: 4_backend/4_2_http -[Step 4.3]: 4_backend/4_3_api -[Step 4 Summary Task]: 4_backend/README.md#task -[Step 5]: 5_zero2prod -[Step 5.1]: 5_zero2prod/3_chapter -[Step 5.2]: 5_zero2prod/4_chapter -[Step 5.3]: 5_zero2prod/5_chapter -[Step 5.4]: 5_zero2prod/6_chapter -[Step 5.5]: 5_zero2prod/7_chapter -[Step 5.6]: 5_zero2prod/10_chapter -[Step 6]: 6_project -[Step 6.1]: 6_project/README.md#step-61-agree-on-your-capstone-project -[Step 6.2]: 6_project/README.md#step-62-get-approvement-of-basic-implementation-from-the-first-mentor -[Step 6.3]: 6_project/README.md#step-63-get-4-reviews-from-peers-and-mentors -[Step 6.4]: 6_project/README.md#step-64-present-your-project +[Task 0]: 0_vocabulary +[Task 1]: 1_concepts +[Task 1.1]: 1_concepts/1_1_default_clone_copy +[Task 1.2]: 1_concepts/1_2_box_pin +[Task 1.3]: 1_concepts/1_3_rc_cell +[Task 1.4]: 1_concepts/1_4_cow +[Task 1.5]: 1_concepts/1_5_convert_cast_deref +[Task 1.6]: 1_concepts/1_6_dispatch +[Task 1.7]: 1_concepts/1_7_sized +[Task 1.8]: 1_concepts/1_8_thread_safety +[Task 1.9]: 1_concepts/1_9_phantom +[Task 1 Summary Task]: 1_concepts/README.md#task +[Task 2]: 2_idioms +[Task 2.1]: 2_idioms/2_1_type_safety +[Task 2.2]: 2_idioms/2_2_mem_replace +[Task 2.3]: 2_idioms/2_3_bound_impl +[Task 2.4]: 2_idioms/2_4_generic_in_type_out +[Task 2.5]: 2_idioms/2_5_exhaustivity +[Task 2.6]: 2_idioms/2_6_sealing +[Task 2 Summary Task]: 2_idioms/README.md#task +[Task 3]: 3_ecosystem +[Task 3.1]: 3_ecosystem/3_1_testing +[Task 3.2]: 3_ecosystem/3_2_macro +[Task 3.3]: 3_ecosystem/3_3_date_time +[Task 3.4]: 3_ecosystem/3_4_regex_parsing +[Task 3.5]: 3_ecosystem/3_5_collections +[Task 3.6]: 3_ecosystem/3_6_serde +[Task 3.7]: 3_ecosystem/3_7_rand_crypto +[Task 3.8]: 3_ecosystem/3_8_log +[Task 3.9]: 3_ecosystem/3_9_cmd_env_conf +[Task 3.10]: 3_ecosystem/3_10_threads +[Task 3.11]: 3_ecosystem/3_11_async +[Task 3 Summary Task]: 3_ecosystem/README.md#task +[Task 4]: 4_backend +[Task 4.1]: 4_backend/4_1_db +[Task 4.2]: 4_backend/4_2_http +[Task 4.3]: 4_backend/4_3_api +[Task 4 Summary Task]: 4_backend/README.md#task +[Task 5]: 5_zero2prod +[Task 5.1]: 5_zero2prod/3_chapter +[Task 5.2]: 5_zero2prod/4_chapter +[Task 5.3]: 5_zero2prod/5_chapter +[Task 5.4]: 5_zero2prod/6_chapter +[Task 5.5]: 5_zero2prod/7_chapter +[Task 5.6]: 5_zero2prod/10_chapter +[Task 6]: 6_project +[Task 6.1]: 6_project/README.md#task-61-agree-on-your-capstone-project +[Task 6.2]: 6_project/README.md#task-62-get-approvement-of-basic-implementation-from-the-first-mentor +[Task 6.3]: 6_project/README.md#task-63-get-4-reviews-from-peers-and-mentors +[Task 6.4]: 6_project/README.md#task-64-present-your-project [Awesome Rust]: https://github.com/rust-unofficial/awesome-rust [Baby Steps]: http://smallcultfollowing.com/babysteps @@ -216,3 +253,6 @@ Rustcamp materials were based on the [Rust Incubator](https://github.com/instrum [Rust Book]: https://doc.rust-lang.org/book [Progress Board]: https://github.com/rust-lang-ua/rustcamp_progress/blob/master/README.md [Graduates' Capstone Projects]: https://github.com/rust-lang-ua/rustcamp_projects + + +[13]: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html diff --git a/faq.md b/faq.md index 3d85aa32..41fbc177 100644 --- a/faq.md +++ b/faq.md @@ -63,14 +63,6 @@ Each task should be submitted as a separate PR on its own branch. Use the follow - "task_1_3" for the third task in the first section, - "task_5_3_11" for the 11th subtask of the third task in the fifth section, -##### *- What is the final task?*
-This is the last task of the section, namely: -- Task_1_10 : 1_concepts/README.md -- Task_2_7 : 2_idioms/README.md -- Task_3_12 : 3_ecosystem/README.md -- Task_4_4 : 4_backend/README.md -Questions should be answered in writing only in them. - ##### *- Should I answer theoretical questions in PR?*
Only in the [final tasks](https://github.com/rust-lang-ua/rustcamp/edit/master/faq.md#--what-is-the-final-task). In tasks that are not final, you do not need to answer theoretical questions. For example, in Problems 1_1, 1_2, you do not need to answer the theoretical questions in writing because they are not final. diff --git a/orientation.md b/orientation.md index 0123a498..f5621493 100644 --- a/orientation.md +++ b/orientation.md @@ -44,7 +44,7 @@ Also, Rust is not the worst choice nowadays: - [A large and friendly community](https://medium.com/mozilla-tech/growing-the-rust-community-6b6d23725085) - [Trending language: 7 years in a row as a favorite programming language ](https://survey.stackoverflow.co/2022/#section-most-loved-dreaded-and-wanted-programming-scripting-and-markup-languages) -- [Fast](https://levelup.gitconnected.com/which-is-faster-rust-or-c-lets-find-out-who-is-the-usain-bolt-87495c774c8) and [secure](https://vegibit.com/is-rust-the-future-of-systems-programming/) +- [Fast](https://levelup.gitconnected.com/which-is-faster-rust-or-c-lets-find-out-who-is-the-usain-bolt-87495c774c8) and [secure](https://medium.com/@elvisouma943/the-future-of-systems-programming-e99a46e3739b) - [Recognition by world leaders: Mozilla, Dropbox, Cloudflare, Discord, AWS](https://www.rust-lang.org/production/users) - [Rich ecosystem: cargo out of the box](https://lib.rs/stats) - Rust in the cores of [Linux](https://www.infoq.com/news/2022/12/linux-6-1-rust/) and [Windows](https://www.theregister.com/2023/04/27/microsoft_windows_rust/) : the language will not disappear and will continue to evolve @@ -62,8 +62,6 @@ Expect to join calls with your fellow learners and mentors four days a week. Dur ### Topology of curriculum -In most contexts, the terms chapter and step can be used interchangeably. - The boot camp is divided into four parts: 1. General part: chapters 0, 1, 2, 3 @@ -132,14 +130,14 @@ Please be **respectful and polite** to peers and mentors. ### Deadlines -__Soft Deadline: Thursday 00:00__ +__Soft Deadline: Thursday 23:59__ - By this time, you should have submitted your latest version of the PR - If you do not do this, you get a foul - Mentors check your PR over the next day or two, and by Sunday you receive an aprove - 3 fouls received means expulsion from the bootcamp > 💡 If you still have corrections to make after Thursday, you can make them before the hard deadline - but this is also a foul (so try to have the final version of your PR by Thursday) -__Hard deadline: Sunday 00:00__ +__Hard deadline: Sunday 23:59__ - If by this time you still haven't submitted your PR or made the last edits, you are out of the bootcamp ### Expulsion @@ -175,12 +173,12 @@ This course is continually evolving, and it's important to stay updated with the ## Submitting Solutions -For each chapter or step of the rustcamp, you should create and submit a separate [PR (pull request)][PR]. Make sure to give your PR a [relevant title](https://github.com/rust-lang-ua/rustcamp/blob/master/faq.md#--how-should-i-name-pr). After you've completed your pull request, please remove any markers like "NOT READY", "DRAFT", or "WIP" from the title and specify [our bot](https://github.com/1tbot) as a reviewer and tag all of your mentors in the comments section. +For each task of the rustcamp, you should create and submit a separate [PR (pull request)][PR]. Make sure to give your PR a [relevant title](https://github.com/rust-lang-ua/rustcamp/blob/master/faq.md#--how-should-i-name-pr). After you've completed your pull request, please remove any markers like "NOT READY", "DRAFT", or "WIP" from the title and specify [our bot](https://github.com/1tbot) as a reviewer and tag all of your mentors in the comments section. Please, don't do PR merge yourself. Before merging the pull request into the main branch, you need to receive approval from at least one mentor. If more than one mentor has reviewed your Pull Request and requested changes, you must receive approval from all involved mentors. If all the conditions are executed, mentors will be able to merge your PR. -Each step of the rustcamp is a [Cargo workspace member][workspace], meaning you can run and test it from the project root using commands like `cargo run -p step_1_8`. We highly recommend using tools like [rustfmt] and [Clippy] while writing your [Rust] code. +Each task of the rustcamp is a [Cargo workspace member][workspace], meaning you can run and test it from the project root using commands like `cargo run -p task_1_8`. We highly recommend using tools like [rustfmt] and [Clippy] while writing your [Rust] code. Never hesitate to reach out to your mentor or lead with questions. However, be aware that you may not always receive a direct answer. Instead, they may guide you towards a path for your own exploration and discovery. Remember, in this learning journey, it's usually the mentor or lead who asks the questions, expecting thorough and precise responses from you.