├── .github └── dependabot.yml ├── .gitignore ├── CODEOWNERS ├── CONTRIBUTING.adoc ├── LICENSE ├── README.adoc ├── chapter-1 ├── 1-null-pointer-dereference │ ├── c │ │ ├── null_pointer │ │ ├── null_pointer.c │ │ ├── null_pointer_safe │ │ └── null_pointer_safe.c │ └── rust │ │ ├── null_pointer │ │ ├── null_pointer.rs │ │ ├── null_pointer_safe │ │ └── null_pointer_safe.rs ├── 10-controlled-unsafe-operations │ └── rust │ │ ├── unsafe │ │ └── unsafe.rs ├── 2-buffer-overflow │ ├── c │ │ ├── buffer_overflow │ │ └── buffer_overflow.c │ └── rust │ │ ├── buffer_ovreflow │ │ └── buffer_ovreflow.rs ├── 3-garbage-collector │ ├── c++ │ │ ├── gc │ │ └── gc.cpp │ └── rust │ │ ├── gc │ │ └── gc.rs ├── 4-the-era-of-multithreading-and-parallelism │ ├── c++ │ │ ├── thread │ │ └── thread.cpp │ └── rust │ │ ├── thread │ │ ├── thread.rs │ │ ├── thread_with_mutex │ │ └── thread_with_mutex.rs ├── 5-the-power-of-pattern-matching │ └── rust │ │ ├── pattern │ │ └── pattern.rs ├── 6-lifetimes-for-memory-safety │ └── rust │ │ ├── lifetimes │ │ └── lifetimes.rs ├── 7-zero-cost-abstractions-for-performance │ └── rust │ │ ├── zero_cost_abstractions │ │ └── zero_cost_abstractions.rs ├── 8-foreign-function-interface │ └── rust │ │ ├── external_lib.c │ │ ├── external_lib.h │ │ ├── external_lib.o │ │ ├── libexternal_lib.a │ │ ├── main │ │ └── main.rs ├── 9-robust-error-handling-with-result-and-option │ └── rust │ │ ├── content.txt │ │ ├── error_handling │ │ └── error_handling.rs └── chapter-1.ipynb ├── chapter-2 └── chapter-2.ipynb ├── chapter-3 └── chapter-3.ipynb ├── chapter-4 ├── chapter-4.ipynb ├── file.txt └── my_set.json ├── chapter-5 ├── chapter-5.ipynb └── esports_data.csv ├── chapter-6 ├── chapter-6.ipynb └── example.txt ├── chapter-7 └── chapter-7.ipynb ├── chapter-8 ├── 1-find-replace │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 2-multiple-args │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 3-flag-args │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 4-advanced-args │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 5-reading-files │ ├── Cargo.lock │ ├── Cargo.toml │ ├── file.txt │ └── src │ │ └── main.rs ├── 6-find-replace-logic │ ├── Cargo.lock │ ├── Cargo.toml │ ├── file.txt │ └── src │ │ └── main.rs ├── 7-writing-to-file │ ├── Cargo.lock │ ├── Cargo.toml │ ├── file.txt │ └── src │ │ └── main.rs ├── 8-case-insensitive-search │ ├── Cargo.lock │ ├── Cargo.toml │ ├── file.txt │ └── src │ │ └── main.rs ├── 9-multiple-input-files │ ├── Cargo.lock │ ├── Cargo.toml │ ├── file1.txt │ ├── file2.txt │ ├── file3.txt │ └── src │ │ └── main.rs └── chapter-8.ipynb ├── chapter-9 ├── asynchronous-networking │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── binary_file.bin ├── binary_output.bin ├── chapter-9.ipynb ├── config.json ├── example.txt ├── hard_link_to_source.txt ├── input.txt ├── large_file.bin ├── locked_file.txt ├── networking-libraries │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── new_file.txt ├── output.txt ├── path_to_directory │ ├── config.json │ └── new_file.txt ├── shared_file.txt ├── source_file.txt └── symlink_to_target.txt ├── chapter_10 └── chapter-10.ipynb ├── chapter_11 ├── 1-basic-test-function │ ├── Cargo.lock │ ├── Cargo.toml │ ├── cobertura.xml │ └── src │ │ └── main.rs ├── 2-test-modules │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs └── chapter-11.ipynb ├── chapter_12 ├── 1-building-networked-applications │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 2-asynchronous-programming │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 3-asynchronous-tcp-server │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── 4-handle-http-requests-with-hyper │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── chapter-12.ipynb └── file.txt ├── chapter_13 └── chapter-13.ipynb ├── chapter_14 └── chapter-14.ipynb └── chapter_15 ├── crypto ├── .appveyor.yml ├── .github │ └── dependabot.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── index.css ├── index.html ├── src │ └── lib.rs └── tests │ └── web.rs ├── data-viz ├── .appveyor.yml ├── .github │ └── dependabot.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── index.html ├── src │ └── lib.rs └── tests │ └── web.rs ├── image-processing ├── .appveyor.yml ├── .github │ └── dependabot.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── index.css ├── index.html ├── src │ └── lib.rs └── tests │ └── web.rs ├── mathlikeanim-rs ├── .appveyor.yml ├── .github │ └── dependabot.yml ├── .travis.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── index.css ├── index.html └── src │ └── lib.rs ├── my_wasm_project ├── .appveyor.yml ├── .github │ └── dependabot.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── index.html ├── src │ ├── lib.rs │ └── utils.rs └── tests │ └── web.rs └── networking ├── .appveyor.yml ├── .github └── dependabot.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE_APACHE ├── LICENSE_MIT ├── README.md ├── index.css ├── index.html ├── src └── lib.rs └── tests └── web.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "cargo" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints/ 2 | **/target/** -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | @wiseaidev 2 | @OrangeAVA -------------------------------------------------------------------------------- /CONTRIBUTING.adoc: -------------------------------------------------------------------------------- 1 | = Contribution Guidelines 👷 2 | 3 | :toc: 4 | 5 | == Welcome 👋 6 | 7 | Thank you for considering contributing to the Rust Lang Book repository! Your contributions, no matter how big or small, play a crucial role in improving the quality and content of the book. We appreciate your effort and dedication to making this resource better for the Rust community. 8 | 9 | == How to Contribute 🚀 10 | 11 | Contributing to the Rust Lang Book repository is easy! Follow these steps to get started: 12 | 13 | === 1. Fork the Repository 🍴 14 | 15 | Start by forking the repository to your GitHub account. This will create a copy of the repository under your account, allowing you to make changes without affecting the main project. 16 | 17 | === 2. Clone the Repository 💻 18 | 19 | Clone the forked repository to your local machine using the following command: 20 | 21 | [source,shell] 22 | ---- 23 | $ git clone https://github.com/your-username/rust-lang-book.git 24 | ---- 25 | 26 | Replace "your-username" with your GitHub username. 27 | 28 | === 3. Create a Branch for Local Development 🌿 29 | 30 | Create a new branch for your local development with a descriptive name for your bug fix or feature: 31 | 32 | [source,shell] 33 | ---- 34 | $ git checkout -b name-of-your-bugfix-or-feature 35 | ---- 36 | 37 | Now you can make your changes locally. 38 | 39 | === 4. Make Changes ✏️ 40 | 41 | Make the desired changes to the content or address any issues you've identified. Ensure that your changes align with the project's goals and coding standards. 42 | 43 | === 5. Test Your Changes 🧪 44 | 45 | If applicable, test your changes to ensure they work as expected. This is especially important if you're updating or adding code in the Jupyter notebooks. 46 | 47 | === 6. Commit Your Changes ✅ 48 | 49 | Commit your changes with clear and concise commit messages. This helps maintain a clean and readable version history. 50 | 51 | [source,shell] 52 | ---- 53 | $ git add . 54 | $ git commit -m "Brief description of the changes" 55 | ---- 56 | 57 | === 7. Push Changes 📌 58 | 59 | Push your changes to your forked repository on GitHub: 60 | 61 | [source,shell] 62 | ---- 63 | $ git push origin name-of-your-bugfix-or-feature 64 | ---- 65 | 66 | === 8. Create a Pull Request 🔀 67 | 68 | Navigate to your forked repository on GitHub and create a pull request (PR) to merge your changes into the main repository. Provide a detailed description of your changes, and our team will review your PR as soon as possible. 69 | 70 | == Additional Contribution Opportunities 💡 71 | 72 | Aside from content improvements, you can also contribute by keeping the libraries code in each Jupyter notebook up-to-date. Ensure that dependencies and libraries are bumped to the latest versions for a better learning experience. 73 | 74 | Thank you for your contribution to the Rust Lang Book repository! 🎉 75 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 AVA™ and Mahmoud Harmouch 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 | -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/c/null_pointer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/1-null-pointer-dereference/c/null_pointer -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/c/null_pointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int *ptr = NULL; 5 | *ptr = 5; 6 | return 0; 7 | } 8 | 9 | // gcc null_pointer.c -o null_pointer && ./null_pointer 10 | // Output: Segmentation fault (core dumped) 11 | -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/c/null_pointer_safe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/1-null-pointer-dereference/c/null_pointer_safe -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/c/null_pointer_safe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | int *ptr = malloc(sizeof(int)); 6 | if (ptr == NULL) { // ① 7 | printf("Error: memory allocation failed"); 8 | } else { 9 | *ptr = 5; 10 | } 11 | } 12 | 13 | // gcc null_pointer_safe.c -o null_pointer_safe && ./null_pointer_safe 14 | // Output: Nothing 15 | -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/rust/null_pointer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/1-null-pointer-dereference/rust/null_pointer -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/rust/null_pointer.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let ptr: *const i32 = std::ptr::null(); 3 | let value = unsafe { *ptr }; 4 | println!("Value: {}", value); 5 | } 6 | 7 | // rustc null_pointer.rs && ./null_pointer 8 | // Segmentation fault (core dumped) -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/rust/null_pointer_safe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/1-null-pointer-dereference/rust/null_pointer_safe -------------------------------------------------------------------------------- /chapter-1/1-null-pointer-dereference/rust/null_pointer_safe.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut vec = vec![1, 2, 3]; 3 | // let mut vec: Vec = vec![]; 4 | let item = vec.pop(); 5 | match item { 6 | Some(val) => println!("Popped value: {}", val), 7 | None => println!("Vector is empty"), 8 | } 9 | } 10 | 11 | // rustc null_pointer.rs 12 | // Output: Popped value: 3 -------------------------------------------------------------------------------- /chapter-1/10-controlled-unsafe-operations/rust/unsafe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/10-controlled-unsafe-operations/rust/unsafe -------------------------------------------------------------------------------- /chapter-1/10-controlled-unsafe-operations/rust/unsafe.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut data = [1, 2, 3, 4, 5]; 3 | let data_ptr = data.as_mut_ptr(); 4 | 5 | unsafe { 6 | *data_ptr.offset(2) = 10; 7 | } 8 | 9 | println!("Modified data: {:?}", data); 10 | } 11 | 12 | // Modified data: [1, 2, 10, 4, 5] 13 | -------------------------------------------------------------------------------- /chapter-1/2-buffer-overflow/c/buffer_overflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/2-buffer-overflow/c/buffer_overflow -------------------------------------------------------------------------------- /chapter-1/2-buffer-overflow/c/buffer_overflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | char buffer[5]; 6 | strcpy(buffer, "Overflowing Content!"); 7 | printf("%s\n", buffer); 8 | return 0; 9 | } 10 | 11 | // gcc -Wstringop-overflow=0 -fno-stack-protector buffer_overflow.c -o buffer_overflow && ./buffer_overflow 12 | 13 | // Overflowing Content! 14 | // Segmentation fault (core dumped) 15 | -------------------------------------------------------------------------------- /chapter-1/2-buffer-overflow/rust/buffer_ovreflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/2-buffer-overflow/rust/buffer_ovreflow -------------------------------------------------------------------------------- /chapter-1/2-buffer-overflow/rust/buffer_ovreflow.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut buffer: [u8; 5] = [0; 5]; 3 | let data = b"Overflowing Content!"; 4 | buffer[..data.len()].copy_from_slice(data); 5 | println!("Buffer: {:?}", buffer); 6 | } 7 | // rustc buffer_ovreflow.rs && ./buffer_ovreflow 8 | // thread 'main' panicked at 'range end index 20 out of range for slice of length 5', buffer_ovreflow.rs:4:5 9 | -------------------------------------------------------------------------------- /chapter-1/3-garbage-collector/c++/gc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/3-garbage-collector/c++/gc -------------------------------------------------------------------------------- /chapter-1/3-garbage-collector/c++/gc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Resource { 5 | std::vector data; 6 | }; 7 | 8 | int main() { 9 | Resource resource; 10 | resource.data = {1, 2, 3, 4, 5}; 11 | // Manual memory cleanup for 'data' is necessary before going out of scope 12 | return 0; 13 | } 14 | 15 | // g++ gc.cpp -o gc && ./gc 16 | -------------------------------------------------------------------------------- /chapter-1/3-garbage-collector/rust/gc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/3-garbage-collector/rust/gc -------------------------------------------------------------------------------- /chapter-1/3-garbage-collector/rust/gc.rs: -------------------------------------------------------------------------------- 1 | struct Resource { 2 | data: Vec, 3 | } 4 | fn main() { 5 | let resource = Resource { 6 | data: vec![1, 2, 3, 4, 5], 7 | }; 8 | } 9 | // rustc buffer_ovreflow.rs && ./buffer_ovreflow 10 | // thread 'main' panicked at 'range end index 20 out of range for slice of length 5', buffer_ovreflow.rs:4:5 11 | -------------------------------------------------------------------------------- /chapter-1/4-the-era-of-multithreading-and-parallelism/c++/thread: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/4-the-era-of-multithreading-and-parallelism/c++/thread -------------------------------------------------------------------------------- /chapter-1/4-the-era-of-multithreading-and-parallelism/c++/thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void process_item(int item) { 6 | std::cout << "Processed: " << item * 2 << std::endl; 7 | } 8 | 9 | int main() { 10 | std::vector data = {1, 2, 3, 4, 5}; 11 | std::vector threads; 12 | 13 | for (const auto &item : data) { 14 | threads.push_back(std::thread(process_item, item)); 15 | } 16 | 17 | for (auto &thread : threads) { 18 | thread.join(); 19 | } 20 | 21 | return 0; 22 | } 23 | 24 | // Processed: Processed: 26 25 | 26 | // Processed: 4 27 | // Processed: 8 28 | // Processed: 10 29 | -------------------------------------------------------------------------------- /chapter-1/4-the-era-of-multithreading-and-parallelism/rust/thread: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/4-the-era-of-multithreading-and-parallelism/rust/thread -------------------------------------------------------------------------------- /chapter-1/4-the-era-of-multithreading-and-parallelism/rust/thread.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | fn main() { 4 | let data = vec![1, 2, 3, 4, 5]; 5 | let mut handles = vec![]; 6 | 7 | for &item in &data { 8 | handles.push(thread::spawn(move || { 9 | println!("Processed: {}", item * 2); 10 | })); 11 | } 12 | 13 | for handle in handles { 14 | handle.join().unwrap(); 15 | } 16 | 17 | } 18 | 19 | // rustc thread.rs && ./thread 20 | 21 | // Processed: 2 22 | // Processed: 6 23 | // Processed: 4 24 | // Processed: 8 25 | // Processed: 10 26 | -------------------------------------------------------------------------------- /chapter-1/4-the-era-of-multithreading-and-parallelism/rust/thread_with_mutex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/4-the-era-of-multithreading-and-parallelism/rust/thread_with_mutex -------------------------------------------------------------------------------- /chapter-1/4-the-era-of-multithreading-and-parallelism/rust/thread_with_mutex.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{Arc, Mutex}; 2 | use std::thread; 3 | 4 | fn main() { 5 | let data = Arc::new(Mutex::new(0)); 6 | 7 | let handles: Vec<_> = (0..10) 8 | .map(|_| { 9 | let data = data.clone(); 10 | thread::spawn(move || { 11 | let mut data = data.lock().unwrap(); 12 | *data += 1; 13 | }) 14 | }) 15 | .collect(); 16 | 17 | for handle in handles { 18 | handle.join().unwrap(); 19 | } 20 | 21 | println!("Final data value: {:?}", *data.lock().unwrap()); 22 | } 23 | 24 | // Final data value: 10 -------------------------------------------------------------------------------- /chapter-1/5-the-power-of-pattern-matching/rust/pattern: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/5-the-power-of-pattern-matching/rust/pattern -------------------------------------------------------------------------------- /chapter-1/5-the-power-of-pattern-matching/rust/pattern.rs: -------------------------------------------------------------------------------- 1 | enum Shape { 2 | Circle(f64), 3 | Rectangle(f64, f64), 4 | Triangle(f64, f64, f64), 5 | } 6 | 7 | fn area(shape: Shape) -> f64 { 8 | match shape { 9 | Shape::Circle(radius) => std::f64::consts::PI * radius * radius, 10 | Shape::Rectangle(width, height) => width * height, 11 | Shape::Triangle(a, b, c) => { 12 | let s = (a + b + c) / 2.0; 13 | (s * (s - a) * (s - b) * (s - c)).sqrt() 14 | } 15 | } 16 | } 17 | 18 | fn main() { 19 | print!("{:?}", area(Shape::Circle(32.0))); 20 | } 21 | 22 | // rustc pattern.rs && /pattern 23 | // 3216.990877275948 -------------------------------------------------------------------------------- /chapter-1/6-lifetimes-for-memory-safety/rust/lifetimes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/6-lifetimes-for-memory-safety/rust/lifetimes -------------------------------------------------------------------------------- /chapter-1/6-lifetimes-for-memory-safety/rust/lifetimes.rs: -------------------------------------------------------------------------------- 1 | fn longest_common_prefix<'a>(x: &'a str, y: &'a str) -> &'a str { 2 | let min_length = std::cmp::min(x.len(), y.len()); 3 | let bytes_x = x.as_bytes(); 4 | let bytes_y = y.as_bytes(); 5 | 6 | for i in 0..min_length { 7 | if bytes_x[i] != bytes_y[i] { 8 | return &x[..i]; 9 | } 10 | } 11 | 12 | &x[..min_length] 13 | } 14 | 15 | fn main() { 16 | let string1 = "abc"; 17 | let result; 18 | { 19 | let string2 = "abdef"; 20 | result = longest_common_prefix(string1, string2); 21 | } 22 | println!("The longest common prefix is: {}", result); 23 | } 24 | 25 | // rustc lifetimes.rs && ./lifetimes 26 | // The longest common prefix is: ab -------------------------------------------------------------------------------- /chapter-1/7-zero-cost-abstractions-for-performance/rust/zero_cost_abstractions: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/7-zero-cost-abstractions-for-performance/rust/zero_cost_abstractions -------------------------------------------------------------------------------- /chapter-1/7-zero-cost-abstractions-for-performance/rust/zero_cost_abstractions.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | fn main() { 4 | let data = vec![1, 2, 3, 4, 5]; 5 | let shared_data = std::sync::Arc::new(data); 6 | 7 | let handles: Vec<_> = (0..5).map(|i| { 8 | let shared_data = shared_data.clone(); 9 | thread::spawn(move || { 10 | let local_sum: i32 = shared_data.iter().sum(); 11 | println!("Thread {} Sum: {}", i, local_sum); 12 | }) 13 | }).collect(); 14 | 15 | for handle in handles { 16 | handle.join().unwrap(); 17 | } 18 | } 19 | 20 | 21 | // Thread 0 Sum: 15 22 | // Thread 2 Sum: 15 23 | // Thread 4 Sum: 15 24 | // Thread 1 Sum: 15 25 | // Thread 3 Sum: 15 26 | -------------------------------------------------------------------------------- /chapter-1/8-foreign-function-interface/rust/external_lib.c: -------------------------------------------------------------------------------- 1 | #include "external_lib.h" 2 | #include 3 | 4 | void process_data(unsigned char *data, size_t length) { 5 | for (size_t i = 0; i < length; i++) { 6 | printf("%u ", data[i]); 7 | } 8 | printf("\n"); 9 | } 10 | -------------------------------------------------------------------------------- /chapter-1/8-foreign-function-interface/rust/external_lib.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef EXTERNAL_LIB_H 3 | #define EXTERNAL_LIB_H 4 | 5 | void process_data(unsigned char *data, size_t length); 6 | 7 | #endif // EXTERNAL_LIB_H 8 | -------------------------------------------------------------------------------- /chapter-1/8-foreign-function-interface/rust/external_lib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/8-foreign-function-interface/rust/external_lib.o -------------------------------------------------------------------------------- /chapter-1/8-foreign-function-interface/rust/libexternal_lib.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/8-foreign-function-interface/rust/libexternal_lib.a -------------------------------------------------------------------------------- /chapter-1/8-foreign-function-interface/rust/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/8-foreign-function-interface/rust/main -------------------------------------------------------------------------------- /chapter-1/8-foreign-function-interface/rust/main.rs: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | fn process_data(data: *mut u8, length: usize); 3 | } 4 | 5 | fn main() { 6 | let mut data: Vec = vec![1, 2, 3, 4, 5]; 7 | 8 | unsafe { 9 | process_data(data.as_mut_ptr(), data.len()); 10 | } 11 | } 12 | 13 | // gcc -c external_lib.c -o external_lib.o 14 | // ar rcs libexternal_lib.a external_lib.o 15 | 16 | // rustc -L . -o main main.rs -l external_lib 17 | // ./main 18 | // 1 2 3 4 5 -------------------------------------------------------------------------------- /chapter-1/9-robust-error-handling-with-result-and-option/rust/content.txt: -------------------------------------------------------------------------------- 1 | line 1 2 | line 2 3 | line 3 4 | -------------------------------------------------------------------------------- /chapter-1/9-robust-error-handling-with-result-and-option/rust/error_handling: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-1/9-robust-error-handling-with-result-and-option/rust/error_handling -------------------------------------------------------------------------------- /chapter-1/9-robust-error-handling-with-result-and-option/rust/error_handling.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{Read, Error}; 3 | 4 | fn read_file_contents(filename: &str) -> Result { 5 | let mut file = File::open(filename)?; 6 | let mut contents = String::new(); 7 | file.read_to_string(&mut contents)?; 8 | Ok(contents) 9 | } 10 | 11 | fn main() { 12 | let filename = "content.txt"; 13 | 14 | match read_file_contents(filename) { 15 | Ok(contents) => { 16 | println!("File contents:\n{}", contents); 17 | } 18 | Err(err) => { 19 | eprintln!("Error reading file: {}", err); 20 | } 21 | } 22 | } 23 | 24 | // File contents: 25 | // line 1 26 | // line 2 27 | // line 3 28 | // 29 | -------------------------------------------------------------------------------- /chapter-4/file.txt: -------------------------------------------------------------------------------- 1 | Hello 2 | World -------------------------------------------------------------------------------- /chapter-4/my_set.json: -------------------------------------------------------------------------------- 1 | {"my_set":[3,1,2]} -------------------------------------------------------------------------------- /chapter-5/esports_data.csv: -------------------------------------------------------------------------------- 1 | MatchDate,Team1,Team2,Win1,Win2,Kills1,Kills2,Deaths1,Deaths2,Assists1,Assists2,Objectives1,Objectives2,TournamentImportance,Region 2 | 2023-01-01,TeamA,TeamB,1,0,20,10,5,15,15,5,3,2,0.9,NA 3 | 2023-01-02,TeamC,TeamD,0,1,15,20,10,5,10,15,2,3,0.8,NA 4 | 2023-01-03,TeamA,TeamC,0,1,18,22,8,12,12,18,4,5,0.9,NA 5 | 2023-01-04,TeamB,TeamD,1,0,25,12,6,15,20,8,4,3,0.8,NA 6 | 2023-01-05,TeamA,TeamD,1,0,22,18,7,14,14,20,5,6,0.9,NA 7 | 2023-01-06,TeamB,TeamC,0,1,15,25,10,8,10,20,3,4,0.8,NA 8 | 2023-01-07,TeamA,TeamC,1,0,24,20,8,15,16,18,4,4,0.9,NA 9 | 2023-01-08,TeamB,TeamD,1,0,20,15,6,12,12,15,3,2,0.8,NA 10 | -------------------------------------------------------------------------------- /chapter-6/example.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-6/example.txt -------------------------------------------------------------------------------- /chapter-8/1-find-replace/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.3" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "clap" 55 | version = "4.4.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 58 | dependencies = [ 59 | "clap_builder", 60 | "clap_derive", 61 | ] 62 | 63 | [[package]] 64 | name = "clap_builder" 65 | version = "4.4.11" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 68 | dependencies = [ 69 | "anstream", 70 | "anstyle", 71 | "clap_lex", 72 | "strsim", 73 | ] 74 | 75 | [[package]] 76 | name = "clap_derive" 77 | version = "4.4.7" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 80 | dependencies = [ 81 | "heck", 82 | "proc-macro2", 83 | "quote", 84 | "syn", 85 | ] 86 | 87 | [[package]] 88 | name = "clap_lex" 89 | version = "0.6.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 92 | 93 | [[package]] 94 | name = "colorchoice" 95 | version = "1.0.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 98 | 99 | [[package]] 100 | name = "find-replace" 101 | version = "0.1.0" 102 | dependencies = [ 103 | "clap", 104 | ] 105 | 106 | [[package]] 107 | name = "heck" 108 | version = "0.4.1" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 111 | 112 | [[package]] 113 | name = "proc-macro2" 114 | version = "1.0.70" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 117 | dependencies = [ 118 | "unicode-ident", 119 | ] 120 | 121 | [[package]] 122 | name = "quote" 123 | version = "1.0.33" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 126 | dependencies = [ 127 | "proc-macro2", 128 | ] 129 | 130 | [[package]] 131 | name = "strsim" 132 | version = "0.10.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 135 | 136 | [[package]] 137 | name = "syn" 138 | version = "2.0.39" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 141 | dependencies = [ 142 | "proc-macro2", 143 | "quote", 144 | "unicode-ident", 145 | ] 146 | 147 | [[package]] 148 | name = "unicode-ident" 149 | version = "1.0.12" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 152 | 153 | [[package]] 154 | name = "utf8parse" 155 | version = "0.2.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 158 | 159 | [[package]] 160 | name = "windows-sys" 161 | version = "0.52.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 164 | dependencies = [ 165 | "windows-targets", 166 | ] 167 | 168 | [[package]] 169 | name = "windows-targets" 170 | version = "0.52.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 173 | dependencies = [ 174 | "windows_aarch64_gnullvm", 175 | "windows_aarch64_msvc", 176 | "windows_i686_gnu", 177 | "windows_i686_msvc", 178 | "windows_x86_64_gnu", 179 | "windows_x86_64_gnullvm", 180 | "windows_x86_64_msvc", 181 | ] 182 | 183 | [[package]] 184 | name = "windows_aarch64_gnullvm" 185 | version = "0.52.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 188 | 189 | [[package]] 190 | name = "windows_aarch64_msvc" 191 | version = "0.52.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 194 | 195 | [[package]] 196 | name = "windows_i686_gnu" 197 | version = "0.52.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 200 | 201 | [[package]] 202 | name = "windows_i686_msvc" 203 | version = "0.52.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 206 | 207 | [[package]] 208 | name = "windows_x86_64_gnu" 209 | version = "0.52.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 212 | 213 | [[package]] 214 | name = "windows_x86_64_gnullvm" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 218 | 219 | [[package]] 220 | name = "windows_x86_64_msvc" 221 | version = "0.52.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 224 | -------------------------------------------------------------------------------- /chapter-8/1-find-replace/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "find-replace" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/1-find-replace/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command( 5 | author = "Mahmoud Harmouch", 6 | version = "1.0", 7 | about = "A command-line find and replace utility", 8 | name = "find-replace" 9 | )] 10 | struct Args { 11 | /// Sets the input file to process 12 | #[arg(short = 'i', long = "input")] 13 | input: String, 14 | } 15 | 16 | fn main() { 17 | // Access and use the `input` argument here 18 | let args = Args::parse(); 19 | 20 | println!("Parsed Input file name: {}!", args.input); 21 | } 22 | -------------------------------------------------------------------------------- /chapter-8/2-multiple-args/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.3" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "clap" 55 | version = "4.4.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 58 | dependencies = [ 59 | "clap_builder", 60 | "clap_derive", 61 | ] 62 | 63 | [[package]] 64 | name = "clap_builder" 65 | version = "4.4.11" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 68 | dependencies = [ 69 | "anstream", 70 | "anstyle", 71 | "clap_lex", 72 | "strsim", 73 | ] 74 | 75 | [[package]] 76 | name = "clap_derive" 77 | version = "4.4.7" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 80 | dependencies = [ 81 | "heck", 82 | "proc-macro2", 83 | "quote", 84 | "syn", 85 | ] 86 | 87 | [[package]] 88 | name = "clap_lex" 89 | version = "0.6.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 92 | 93 | [[package]] 94 | name = "colorchoice" 95 | version = "1.0.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 98 | 99 | [[package]] 100 | name = "heck" 101 | version = "0.4.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 104 | 105 | [[package]] 106 | name = "multiple-args" 107 | version = "0.1.0" 108 | dependencies = [ 109 | "clap", 110 | ] 111 | 112 | [[package]] 113 | name = "proc-macro2" 114 | version = "1.0.70" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 117 | dependencies = [ 118 | "unicode-ident", 119 | ] 120 | 121 | [[package]] 122 | name = "quote" 123 | version = "1.0.33" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 126 | dependencies = [ 127 | "proc-macro2", 128 | ] 129 | 130 | [[package]] 131 | name = "strsim" 132 | version = "0.10.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 135 | 136 | [[package]] 137 | name = "syn" 138 | version = "2.0.39" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 141 | dependencies = [ 142 | "proc-macro2", 143 | "quote", 144 | "unicode-ident", 145 | ] 146 | 147 | [[package]] 148 | name = "unicode-ident" 149 | version = "1.0.12" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 152 | 153 | [[package]] 154 | name = "utf8parse" 155 | version = "0.2.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 158 | 159 | [[package]] 160 | name = "windows-sys" 161 | version = "0.52.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 164 | dependencies = [ 165 | "windows-targets", 166 | ] 167 | 168 | [[package]] 169 | name = "windows-targets" 170 | version = "0.52.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 173 | dependencies = [ 174 | "windows_aarch64_gnullvm", 175 | "windows_aarch64_msvc", 176 | "windows_i686_gnu", 177 | "windows_i686_msvc", 178 | "windows_x86_64_gnu", 179 | "windows_x86_64_gnullvm", 180 | "windows_x86_64_msvc", 181 | ] 182 | 183 | [[package]] 184 | name = "windows_aarch64_gnullvm" 185 | version = "0.52.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 188 | 189 | [[package]] 190 | name = "windows_aarch64_msvc" 191 | version = "0.52.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 194 | 195 | [[package]] 196 | name = "windows_i686_gnu" 197 | version = "0.52.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 200 | 201 | [[package]] 202 | name = "windows_i686_msvc" 203 | version = "0.52.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 206 | 207 | [[package]] 208 | name = "windows_x86_64_gnu" 209 | version = "0.52.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 212 | 213 | [[package]] 214 | name = "windows_x86_64_gnullvm" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 218 | 219 | [[package]] 220 | name = "windows_x86_64_msvc" 221 | version = "0.52.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 224 | -------------------------------------------------------------------------------- /chapter-8/2-multiple-args/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multiple-args" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/2-multiple-args/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command( 5 | author = "Mahmoud Harmouch", 6 | version = "1.0", 7 | about = "A command-line find and replace utility", 8 | name = "Find and Replace" 9 | )] 10 | struct Args { 11 | /// Sets the input file to process 12 | #[arg(short = 'i', long = "input")] 13 | input: String, 14 | /// Sets the pattern to find 15 | #[arg(short = 'f', long = "find")] 16 | find: String, 17 | /// Sets the replacement text 18 | #[arg(short = 'r', long = "replace")] 19 | replace: String, 20 | } 21 | 22 | fn main() { 23 | // Access and use the `input`, `find`, and `replace` arguments here 24 | let _args = Args::parse(); 25 | } 26 | -------------------------------------------------------------------------------- /chapter-8/3-flag-args/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.3" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "clap" 55 | version = "4.4.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 58 | dependencies = [ 59 | "clap_builder", 60 | "clap_derive", 61 | ] 62 | 63 | [[package]] 64 | name = "clap_builder" 65 | version = "4.4.11" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 68 | dependencies = [ 69 | "anstream", 70 | "anstyle", 71 | "clap_lex", 72 | "strsim", 73 | ] 74 | 75 | [[package]] 76 | name = "clap_derive" 77 | version = "4.4.7" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 80 | dependencies = [ 81 | "heck", 82 | "proc-macro2", 83 | "quote", 84 | "syn", 85 | ] 86 | 87 | [[package]] 88 | name = "clap_lex" 89 | version = "0.6.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 92 | 93 | [[package]] 94 | name = "colorchoice" 95 | version = "1.0.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 98 | 99 | [[package]] 100 | name = "flag-args" 101 | version = "0.1.0" 102 | dependencies = [ 103 | "clap", 104 | ] 105 | 106 | [[package]] 107 | name = "heck" 108 | version = "0.4.1" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 111 | 112 | [[package]] 113 | name = "proc-macro2" 114 | version = "1.0.70" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 117 | dependencies = [ 118 | "unicode-ident", 119 | ] 120 | 121 | [[package]] 122 | name = "quote" 123 | version = "1.0.33" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 126 | dependencies = [ 127 | "proc-macro2", 128 | ] 129 | 130 | [[package]] 131 | name = "strsim" 132 | version = "0.10.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 135 | 136 | [[package]] 137 | name = "syn" 138 | version = "2.0.39" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 141 | dependencies = [ 142 | "proc-macro2", 143 | "quote", 144 | "unicode-ident", 145 | ] 146 | 147 | [[package]] 148 | name = "unicode-ident" 149 | version = "1.0.12" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 152 | 153 | [[package]] 154 | name = "utf8parse" 155 | version = "0.2.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 158 | 159 | [[package]] 160 | name = "windows-sys" 161 | version = "0.52.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 164 | dependencies = [ 165 | "windows-targets", 166 | ] 167 | 168 | [[package]] 169 | name = "windows-targets" 170 | version = "0.52.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 173 | dependencies = [ 174 | "windows_aarch64_gnullvm", 175 | "windows_aarch64_msvc", 176 | "windows_i686_gnu", 177 | "windows_i686_msvc", 178 | "windows_x86_64_gnu", 179 | "windows_x86_64_gnullvm", 180 | "windows_x86_64_msvc", 181 | ] 182 | 183 | [[package]] 184 | name = "windows_aarch64_gnullvm" 185 | version = "0.52.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 188 | 189 | [[package]] 190 | name = "windows_aarch64_msvc" 191 | version = "0.52.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 194 | 195 | [[package]] 196 | name = "windows_i686_gnu" 197 | version = "0.52.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 200 | 201 | [[package]] 202 | name = "windows_i686_msvc" 203 | version = "0.52.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 206 | 207 | [[package]] 208 | name = "windows_x86_64_gnu" 209 | version = "0.52.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 212 | 213 | [[package]] 214 | name = "windows_x86_64_gnullvm" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 218 | 219 | [[package]] 220 | name = "windows_x86_64_msvc" 221 | version = "0.52.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 224 | -------------------------------------------------------------------------------- /chapter-8/3-flag-args/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flag-args" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/3-flag-args/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command( 5 | author = "Mahmoud Harmouch", 6 | version = "1.0", 7 | about = "A command-line find and replace utility", 8 | name = "Find and Replace" 9 | )] 10 | struct Args { 11 | /// Sets the input file to process 12 | #[arg(short = 'i', long = "input")] 13 | input: String, 14 | /// Sets the pattern to find 15 | #[arg(short = 'f', long = "find")] 16 | find: String, 17 | /// Sets the replacement text 18 | #[arg(short = 'r', long = "replace")] 19 | replace: String, 20 | /// Perform a case-insensitive search and replace 21 | #[arg(short = 'c', long = "ignore-case")] 22 | ignore_case: bool, 23 | } 24 | 25 | fn main() { 26 | // Access and use the `input`, `find`, `replace`, and `ignore-case` arguments here 27 | let _args = Args::parse(); 28 | } 29 | -------------------------------------------------------------------------------- /chapter-8/4-advanced-args/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "advanced-args" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "clap", 10 | ] 11 | 12 | [[package]] 13 | name = "anstream" 14 | version = "0.6.5" 15 | source = "registry+https://github.com/rust-lang/crates.io-index" 16 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 17 | dependencies = [ 18 | "anstyle", 19 | "anstyle-parse", 20 | "anstyle-query", 21 | "anstyle-wincon", 22 | "colorchoice", 23 | "utf8parse", 24 | ] 25 | 26 | [[package]] 27 | name = "anstyle" 28 | version = "1.0.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 31 | 32 | [[package]] 33 | name = "anstyle-parse" 34 | version = "0.2.3" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 37 | dependencies = [ 38 | "utf8parse", 39 | ] 40 | 41 | [[package]] 42 | name = "anstyle-query" 43 | version = "1.0.2" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 46 | dependencies = [ 47 | "windows-sys", 48 | ] 49 | 50 | [[package]] 51 | name = "anstyle-wincon" 52 | version = "3.0.2" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 55 | dependencies = [ 56 | "anstyle", 57 | "windows-sys", 58 | ] 59 | 60 | [[package]] 61 | name = "clap" 62 | version = "4.4.11" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 65 | dependencies = [ 66 | "clap_builder", 67 | "clap_derive", 68 | ] 69 | 70 | [[package]] 71 | name = "clap_builder" 72 | version = "4.4.11" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 75 | dependencies = [ 76 | "anstream", 77 | "anstyle", 78 | "clap_lex", 79 | "strsim", 80 | ] 81 | 82 | [[package]] 83 | name = "clap_derive" 84 | version = "4.4.7" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 87 | dependencies = [ 88 | "heck", 89 | "proc-macro2", 90 | "quote", 91 | "syn", 92 | ] 93 | 94 | [[package]] 95 | name = "clap_lex" 96 | version = "0.6.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 99 | 100 | [[package]] 101 | name = "colorchoice" 102 | version = "1.0.0" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 105 | 106 | [[package]] 107 | name = "heck" 108 | version = "0.4.1" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 111 | 112 | [[package]] 113 | name = "proc-macro2" 114 | version = "1.0.70" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 117 | dependencies = [ 118 | "unicode-ident", 119 | ] 120 | 121 | [[package]] 122 | name = "quote" 123 | version = "1.0.33" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 126 | dependencies = [ 127 | "proc-macro2", 128 | ] 129 | 130 | [[package]] 131 | name = "strsim" 132 | version = "0.10.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 135 | 136 | [[package]] 137 | name = "syn" 138 | version = "2.0.39" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 141 | dependencies = [ 142 | "proc-macro2", 143 | "quote", 144 | "unicode-ident", 145 | ] 146 | 147 | [[package]] 148 | name = "unicode-ident" 149 | version = "1.0.12" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 152 | 153 | [[package]] 154 | name = "utf8parse" 155 | version = "0.2.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 158 | 159 | [[package]] 160 | name = "windows-sys" 161 | version = "0.52.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 164 | dependencies = [ 165 | "windows-targets", 166 | ] 167 | 168 | [[package]] 169 | name = "windows-targets" 170 | version = "0.52.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 173 | dependencies = [ 174 | "windows_aarch64_gnullvm", 175 | "windows_aarch64_msvc", 176 | "windows_i686_gnu", 177 | "windows_i686_msvc", 178 | "windows_x86_64_gnu", 179 | "windows_x86_64_gnullvm", 180 | "windows_x86_64_msvc", 181 | ] 182 | 183 | [[package]] 184 | name = "windows_aarch64_gnullvm" 185 | version = "0.52.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 188 | 189 | [[package]] 190 | name = "windows_aarch64_msvc" 191 | version = "0.52.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 194 | 195 | [[package]] 196 | name = "windows_i686_gnu" 197 | version = "0.52.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 200 | 201 | [[package]] 202 | name = "windows_i686_msvc" 203 | version = "0.52.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 206 | 207 | [[package]] 208 | name = "windows_x86_64_gnu" 209 | version = "0.52.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 212 | 213 | [[package]] 214 | name = "windows_x86_64_gnullvm" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 218 | 219 | [[package]] 220 | name = "windows_x86_64_msvc" 221 | version = "0.52.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 224 | -------------------------------------------------------------------------------- /chapter-8/4-advanced-args/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "advanced-args" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/4-advanced-args/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | use clap::{Parser, Subcommand}; 3 | 4 | #[derive(Parser, Debug)] 5 | #[command( 6 | author = "Mahmoud Harmouch", 7 | version = "1.0", 8 | about = "A command-line text manipulation utility", 9 | name = "Text Manipulation Utility" 10 | )] 11 | pub struct Cli { 12 | /// Turn debugging information on. 13 | #[arg(short, long, action = clap::ArgAction::Count)] 14 | debug: u8, 15 | /// Find and Replace commands. 16 | #[command(subcommand)] 17 | pub command: Option 18 | } 19 | 20 | #[derive(Subcommand, Debug)] 21 | pub enum Commands { 22 | /// Subcommand for handling find operations. 23 | Find(FindCommands), 24 | /// Subcommand for handling replace operations. 25 | Replace(ReplaceCommands), 26 | } 27 | 28 | /// Represents find-related commands. 29 | #[derive(Debug, Args)] 30 | pub struct FindCommands { 31 | /// Sets the input file to process 32 | #[clap(short = 'i', long = "input")] 33 | pub input: Option, 34 | /// Sets the pattern to find. 35 | #[clap(short = 'p', long = "pattern")] 36 | pub pattern: Option, 37 | } 38 | 39 | /// Represents repalce-related commands. 40 | #[derive(Debug, Args)] 41 | pub struct ReplaceCommands { 42 | /// Sets the input file to process 43 | #[clap(short = 'i', long = "input")] 44 | pub input: Option, 45 | /// Sets the pattern to find. 46 | #[clap(short = 'p', long = "pattern")] 47 | pub pattern: Option, 48 | /// Sets the replacement text. 49 | #[clap(short = 'r', long = "replace")] 50 | pub replace: Option, 51 | } 52 | 53 | fn main() { 54 | let args = Cli::parse(); 55 | match args.command { 56 | Some(Commands::Find(command)) => { 57 | match command.input { 58 | Some(ref input) => { 59 | // cargo run -- find --input file_name 60 | println!("{:?}", input); 61 | } 62 | None => { 63 | println!("Please provide a file name."); 64 | } 65 | }; 66 | match command.pattern { 67 | Some(ref pattern) => { 68 | // cargo run -- find --pattern custom_pattern 69 | println!("{:?}", pattern); 70 | } 71 | None => { 72 | println!("Please provide a pattern."); 73 | } 74 | }; 75 | } 76 | Some(Commands::Replace(command)) => { 77 | match command.input { 78 | Some(ref input) => { 79 | // cargo run -- replace --input file_name 80 | println!("{:?}", input); 81 | } 82 | None => { 83 | println!("Please provide a file name."); 84 | } 85 | }; 86 | match command.pattern { 87 | Some(ref pattern) => { 88 | // cargo run -- replace --pattern custom_pattern 89 | println!("{:?}", pattern); 90 | } 91 | None => { 92 | println!("Please provide a pattern."); 93 | } 94 | }; 95 | match command.replace { 96 | Some(ref replace) => { 97 | // cargo run -- replace --replace string 98 | println!("{:?}", replace); 99 | } 100 | None => { 101 | println!("Please provide a pattern."); 102 | } 103 | }; 104 | } 105 | None => println!( 106 | "Unknown command. Use '--help' for usage instructions." 107 | ) 108 | }; 109 | } -------------------------------------------------------------------------------- /chapter-8/5-reading-files/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.3" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "clap" 55 | version = "4.4.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 58 | dependencies = [ 59 | "clap_builder", 60 | "clap_derive", 61 | ] 62 | 63 | [[package]] 64 | name = "clap_builder" 65 | version = "4.4.11" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 68 | dependencies = [ 69 | "anstream", 70 | "anstyle", 71 | "clap_lex", 72 | "strsim", 73 | ] 74 | 75 | [[package]] 76 | name = "clap_derive" 77 | version = "4.4.7" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 80 | dependencies = [ 81 | "heck", 82 | "proc-macro2", 83 | "quote", 84 | "syn", 85 | ] 86 | 87 | [[package]] 88 | name = "clap_lex" 89 | version = "0.6.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 92 | 93 | [[package]] 94 | name = "colorchoice" 95 | version = "1.0.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 98 | 99 | [[package]] 100 | name = "heck" 101 | version = "0.4.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 104 | 105 | [[package]] 106 | name = "proc-macro2" 107 | version = "1.0.70" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 110 | dependencies = [ 111 | "unicode-ident", 112 | ] 113 | 114 | [[package]] 115 | name = "quote" 116 | version = "1.0.33" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 119 | dependencies = [ 120 | "proc-macro2", 121 | ] 122 | 123 | [[package]] 124 | name = "reading-files" 125 | version = "0.1.0" 126 | dependencies = [ 127 | "clap", 128 | ] 129 | 130 | [[package]] 131 | name = "strsim" 132 | version = "0.10.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 135 | 136 | [[package]] 137 | name = "syn" 138 | version = "2.0.39" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 141 | dependencies = [ 142 | "proc-macro2", 143 | "quote", 144 | "unicode-ident", 145 | ] 146 | 147 | [[package]] 148 | name = "unicode-ident" 149 | version = "1.0.12" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 152 | 153 | [[package]] 154 | name = "utf8parse" 155 | version = "0.2.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 158 | 159 | [[package]] 160 | name = "windows-sys" 161 | version = "0.52.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 164 | dependencies = [ 165 | "windows-targets", 166 | ] 167 | 168 | [[package]] 169 | name = "windows-targets" 170 | version = "0.52.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 173 | dependencies = [ 174 | "windows_aarch64_gnullvm", 175 | "windows_aarch64_msvc", 176 | "windows_i686_gnu", 177 | "windows_i686_msvc", 178 | "windows_x86_64_gnu", 179 | "windows_x86_64_gnullvm", 180 | "windows_x86_64_msvc", 181 | ] 182 | 183 | [[package]] 184 | name = "windows_aarch64_gnullvm" 185 | version = "0.52.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 188 | 189 | [[package]] 190 | name = "windows_aarch64_msvc" 191 | version = "0.52.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 194 | 195 | [[package]] 196 | name = "windows_i686_gnu" 197 | version = "0.52.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 200 | 201 | [[package]] 202 | name = "windows_i686_msvc" 203 | version = "0.52.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 206 | 207 | [[package]] 208 | name = "windows_x86_64_gnu" 209 | version = "0.52.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 212 | 213 | [[package]] 214 | name = "windows_x86_64_gnullvm" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 218 | 219 | [[package]] 220 | name = "windows_x86_64_msvc" 221 | version = "0.52.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 224 | -------------------------------------------------------------------------------- /chapter-8/5-reading-files/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "reading-files" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/5-reading-files/file.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | -------------------------------------------------------------------------------- /chapter-8/5-reading-files/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | use clap::{Parser, Subcommand}; 3 | use std::fs::File; 4 | use std::io::{self, Read}; 5 | 6 | #[derive(Parser, Debug)] 7 | #[command( 8 | author = "Mahmoud Harmouch", 9 | version = "1.0", 10 | about = "A command-line text manipulation utility", 11 | name = "Text Manipulation Utility" 12 | )] 13 | pub struct Cli { 14 | /// Turn debugging information on. 15 | #[arg(short, long, action = clap::ArgAction::Count)] 16 | debug: u8, 17 | /// Find and Replace commands. 18 | #[command(subcommand)] 19 | pub command: Option 20 | } 21 | 22 | #[derive(Subcommand, Debug)] 23 | pub enum Commands { 24 | /// Subcommand for handling find operations. 25 | Find(FindCommands), 26 | /// Subcommand for handling replace operations. 27 | Replace(ReplaceCommands), 28 | } 29 | 30 | /// Represents find-related commands. 31 | #[derive(Debug, Args)] 32 | pub struct FindCommands { 33 | /// Sets the input file to process 34 | #[clap(short = 'i', long = "input")] 35 | pub input: Option, 36 | /// Sets the pattern to find. 37 | #[clap(short = 'p', long = "pattern")] 38 | pub pattern: Option, 39 | } 40 | 41 | /// Represents repalce-related commands. 42 | #[derive(Debug, Args)] 43 | pub struct ReplaceCommands { 44 | /// Sets the input file to process 45 | #[clap(short = 'i', long = "input")] 46 | pub input: Option, 47 | /// Sets the pattern to find. 48 | #[clap(short = 'p', long = "pattern")] 49 | pub pattern: Option, 50 | /// Sets the replacement text. 51 | #[clap(short = 'r', long = "replace")] 52 | pub replace: Option, 53 | } 54 | 55 | fn read_file_to_string(file_path: &str) -> io::Result { // <1> 56 | let mut file = File::open(file_path)?; // <2> 57 | let mut contents = String::new(); // <2> 58 | file.read_to_string(&mut contents)?; // <2> 59 | 60 | Ok(contents) // <2> 61 | } 62 | 63 | fn main() { // <3> 64 | let args = Cli::parse(); 65 | let input_content; 66 | match args.command { 67 | Some(Commands::Find(command)) => { // <4> 68 | match command.input { 69 | Some(ref input) => { 70 | // cargo run -- find --input file.txt 71 | input_content = read_file_to_string(input).unwrap(); 72 | println!("Input file content: {:?}", input_content); 73 | } 74 | None => { 75 | println!("Please provide a file name."); 76 | } 77 | }; 78 | match command.pattern { 79 | Some(ref pattern) => { 80 | // cargo run -- find --pattern custom_pattern 81 | println!("{:?}", pattern); 82 | } 83 | None => { 84 | println!("Please provide a pattern."); 85 | } 86 | }; 87 | } 88 | Some(Commands::Replace(command)) => { // <5> 89 | match command.input { 90 | Some(ref input) => { 91 | // cargo run -- replace --input file_name 92 | println!("{:?}", input); 93 | } 94 | None => { 95 | println!("Please provide a file name."); 96 | } 97 | }; 98 | match command.pattern { 99 | Some(ref pattern) => { 100 | // cargo run -- replace --pattern custom_pattern 101 | println!("{:?}", pattern); 102 | } 103 | None => { 104 | println!("Please provide a pattern."); 105 | } 106 | }; 107 | match command.replace { 108 | Some(ref replace) => { 109 | // cargo run -- replace --replace string 110 | println!("{:?}", replace); 111 | } 112 | None => { 113 | println!("Please provide a pattern."); 114 | } 115 | }; 116 | } 117 | None => println!( 118 | "Unknown command. Use '--help' for usage instructions." 119 | ) 120 | }; 121 | } -------------------------------------------------------------------------------- /chapter-8/6-find-replace-logic/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.3" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "clap" 55 | version = "4.4.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 58 | dependencies = [ 59 | "clap_builder", 60 | "clap_derive", 61 | ] 62 | 63 | [[package]] 64 | name = "clap_builder" 65 | version = "4.4.11" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 68 | dependencies = [ 69 | "anstream", 70 | "anstyle", 71 | "clap_lex", 72 | "strsim", 73 | ] 74 | 75 | [[package]] 76 | name = "clap_derive" 77 | version = "4.4.7" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 80 | dependencies = [ 81 | "heck", 82 | "proc-macro2", 83 | "quote", 84 | "syn", 85 | ] 86 | 87 | [[package]] 88 | name = "clap_lex" 89 | version = "0.6.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 92 | 93 | [[package]] 94 | name = "colorchoice" 95 | version = "1.0.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 98 | 99 | [[package]] 100 | name = "find-replace-logic" 101 | version = "0.1.0" 102 | dependencies = [ 103 | "clap", 104 | ] 105 | 106 | [[package]] 107 | name = "heck" 108 | version = "0.4.1" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 111 | 112 | [[package]] 113 | name = "proc-macro2" 114 | version = "1.0.70" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 117 | dependencies = [ 118 | "unicode-ident", 119 | ] 120 | 121 | [[package]] 122 | name = "quote" 123 | version = "1.0.33" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 126 | dependencies = [ 127 | "proc-macro2", 128 | ] 129 | 130 | [[package]] 131 | name = "strsim" 132 | version = "0.10.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 135 | 136 | [[package]] 137 | name = "syn" 138 | version = "2.0.39" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 141 | dependencies = [ 142 | "proc-macro2", 143 | "quote", 144 | "unicode-ident", 145 | ] 146 | 147 | [[package]] 148 | name = "unicode-ident" 149 | version = "1.0.12" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 152 | 153 | [[package]] 154 | name = "utf8parse" 155 | version = "0.2.1" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 158 | 159 | [[package]] 160 | name = "windows-sys" 161 | version = "0.52.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 164 | dependencies = [ 165 | "windows-targets", 166 | ] 167 | 168 | [[package]] 169 | name = "windows-targets" 170 | version = "0.52.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 173 | dependencies = [ 174 | "windows_aarch64_gnullvm", 175 | "windows_aarch64_msvc", 176 | "windows_i686_gnu", 177 | "windows_i686_msvc", 178 | "windows_x86_64_gnu", 179 | "windows_x86_64_gnullvm", 180 | "windows_x86_64_msvc", 181 | ] 182 | 183 | [[package]] 184 | name = "windows_aarch64_gnullvm" 185 | version = "0.52.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 188 | 189 | [[package]] 190 | name = "windows_aarch64_msvc" 191 | version = "0.52.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 194 | 195 | [[package]] 196 | name = "windows_i686_gnu" 197 | version = "0.52.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 200 | 201 | [[package]] 202 | name = "windows_i686_msvc" 203 | version = "0.52.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 206 | 207 | [[package]] 208 | name = "windows_x86_64_gnu" 209 | version = "0.52.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 212 | 213 | [[package]] 214 | name = "windows_x86_64_gnullvm" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 218 | 219 | [[package]] 220 | name = "windows_x86_64_msvc" 221 | version = "0.52.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 224 | -------------------------------------------------------------------------------- /chapter-8/6-find-replace-logic/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "find-replace-logic" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/6-find-replace-logic/file.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | -------------------------------------------------------------------------------- /chapter-8/6-find-replace-logic/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | use clap::{Parser, Subcommand}; 3 | use std::fs::File; 4 | use std::io::{self, Read}; 5 | 6 | #[derive(Parser, Debug)] 7 | #[command( 8 | author = "Mahmoud Harmouch", 9 | version = "1.0", 10 | about = "A command-line text manipulation utility", 11 | name = "Text Manipulation Utility" 12 | )] 13 | pub struct Cli { 14 | /// Turn debugging information on. 15 | #[arg(short, long, action = clap::ArgAction::Count)] 16 | debug: u8, 17 | /// Find and Replace commands. 18 | #[command(subcommand)] 19 | pub command: Option 20 | } 21 | 22 | #[derive(Subcommand, Debug)] 23 | pub enum Commands { 24 | /// Subcommand for handling find operations. 25 | Find(FindCommands), 26 | /// Subcommand for handling replace operations. 27 | Replace(ReplaceCommands), 28 | } 29 | 30 | /// Represents find-related commands. 31 | #[derive(Debug, Args)] 32 | pub struct FindCommands { 33 | /// Sets the input file to process 34 | #[clap(short = 'i', long = "input")] 35 | pub input: Option, 36 | /// Sets the pattern to find. 37 | #[clap(short = 'p', long = "pattern")] 38 | pub pattern: Option, 39 | } 40 | 41 | /// Represents repalce-related commands. 42 | #[derive(Debug, Args)] 43 | pub struct ReplaceCommands { 44 | /// Sets the input file to process 45 | #[clap(short = 'i', long = "input")] 46 | pub input: Option, 47 | /// Sets the pattern to find. 48 | #[clap(short = 'p', long = "pattern")] 49 | pub pattern: Option, 50 | /// Sets the replacement text. 51 | #[clap(short = 'r', long = "replace")] 52 | pub replace: Option, 53 | } 54 | 55 | fn read_file_to_string(file_path: &str) -> io::Result { 56 | let mut file = File::open(file_path)?; 57 | let mut contents = String::new(); 58 | file.read_to_string(&mut contents)?; 59 | 60 | Ok(contents) 61 | } 62 | 63 | fn find_and_replace(content: &mut String, pattern: &str, replacement: &str) { 64 | *content = content.replace(pattern, replacement); 65 | } 66 | 67 | fn main() { 68 | let args = Cli::parse(); 69 | let mut input_content = "".to_string(); 70 | let mut pattern_to_find = "".to_string(); 71 | let mut replacement_text = "".to_string(); 72 | 73 | match args.command { 74 | Some(Commands::Find(command)) => { 75 | if let Some(input) = &command.input { 76 | input_content = read_file_to_string(input).unwrap(); 77 | println!("Input file content: {:?}", input_content); 78 | } else { 79 | println!("Please provide a file name."); 80 | } 81 | if let Some(pattern) = &command.pattern { 82 | pattern_to_find = pattern.clone(); 83 | println!("Pattern: {:?}", pattern); 84 | } else { 85 | println!("Please provide a pattern."); 86 | } 87 | } 88 | Some(Commands::Replace(command)) => { 89 | if let Some(input) = &command.input { 90 | input_content = read_file_to_string(input).unwrap(); 91 | println!("Input file content: {:?}", input_content); 92 | } else { 93 | println!("Please provide a file name."); 94 | } 95 | if let Some(pattern) = &command.pattern { 96 | pattern_to_find = pattern.clone(); 97 | println!("Pattern: {:?}", pattern_to_find); 98 | } else { 99 | println!("Please provide a pattern."); 100 | } 101 | if let Some(replace) = &command.replace { 102 | replacement_text = replace.clone(); 103 | println!("Replacement text: {:?}", replacement_text); 104 | } else { 105 | println!("Please provide a replacement text."); 106 | } 107 | } 108 | None => println!("Unknown command. Use '--help' for usage instructions.") 109 | }; 110 | 111 | println!("Content Before: {:?}", input_content); 112 | find_and_replace(&mut input_content, &pattern_to_find, &replacement_text); 113 | println!("Content After: {:?}", input_content); 114 | } -------------------------------------------------------------------------------- /chapter-8/7-writing-to-file/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.3" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "clap" 55 | version = "4.4.11" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 58 | dependencies = [ 59 | "clap_builder", 60 | "clap_derive", 61 | ] 62 | 63 | [[package]] 64 | name = "clap_builder" 65 | version = "4.4.11" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 68 | dependencies = [ 69 | "anstream", 70 | "anstyle", 71 | "clap_lex", 72 | "strsim", 73 | ] 74 | 75 | [[package]] 76 | name = "clap_derive" 77 | version = "4.4.7" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 80 | dependencies = [ 81 | "heck", 82 | "proc-macro2", 83 | "quote", 84 | "syn", 85 | ] 86 | 87 | [[package]] 88 | name = "clap_lex" 89 | version = "0.6.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 92 | 93 | [[package]] 94 | name = "colorchoice" 95 | version = "1.0.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 98 | 99 | [[package]] 100 | name = "heck" 101 | version = "0.4.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 104 | 105 | [[package]] 106 | name = "proc-macro2" 107 | version = "1.0.70" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 110 | dependencies = [ 111 | "unicode-ident", 112 | ] 113 | 114 | [[package]] 115 | name = "quote" 116 | version = "1.0.33" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 119 | dependencies = [ 120 | "proc-macro2", 121 | ] 122 | 123 | [[package]] 124 | name = "strsim" 125 | version = "0.10.0" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 128 | 129 | [[package]] 130 | name = "syn" 131 | version = "2.0.39" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 134 | dependencies = [ 135 | "proc-macro2", 136 | "quote", 137 | "unicode-ident", 138 | ] 139 | 140 | [[package]] 141 | name = "unicode-ident" 142 | version = "1.0.12" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 145 | 146 | [[package]] 147 | name = "utf8parse" 148 | version = "0.2.1" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 151 | 152 | [[package]] 153 | name = "windows-sys" 154 | version = "0.52.0" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 157 | dependencies = [ 158 | "windows-targets", 159 | ] 160 | 161 | [[package]] 162 | name = "windows-targets" 163 | version = "0.52.0" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 166 | dependencies = [ 167 | "windows_aarch64_gnullvm", 168 | "windows_aarch64_msvc", 169 | "windows_i686_gnu", 170 | "windows_i686_msvc", 171 | "windows_x86_64_gnu", 172 | "windows_x86_64_gnullvm", 173 | "windows_x86_64_msvc", 174 | ] 175 | 176 | [[package]] 177 | name = "windows_aarch64_gnullvm" 178 | version = "0.52.0" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 181 | 182 | [[package]] 183 | name = "windows_aarch64_msvc" 184 | version = "0.52.0" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 187 | 188 | [[package]] 189 | name = "windows_i686_gnu" 190 | version = "0.52.0" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 193 | 194 | [[package]] 195 | name = "windows_i686_msvc" 196 | version = "0.52.0" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 199 | 200 | [[package]] 201 | name = "windows_x86_64_gnu" 202 | version = "0.52.0" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 205 | 206 | [[package]] 207 | name = "windows_x86_64_gnullvm" 208 | version = "0.52.0" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 211 | 212 | [[package]] 213 | name = "windows_x86_64_msvc" 214 | version = "0.52.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 217 | 218 | [[package]] 219 | name = "writing-to-file" 220 | version = "0.1.0" 221 | dependencies = [ 222 | "clap", 223 | ] 224 | -------------------------------------------------------------------------------- /chapter-8/7-writing-to-file/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "writing-to-file" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /chapter-8/7-writing-to-file/file.txt: -------------------------------------------------------------------------------- 1 | Hello Rust 2 | -------------------------------------------------------------------------------- /chapter-8/7-writing-to-file/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | use clap::{Parser, Subcommand}; 3 | use std::fs::File; 4 | use std::io::{self, Read, Write}; 5 | 6 | #[derive(Parser, Debug)] 7 | #[command( 8 | author = "Mahmoud Harmouch", 9 | version = "1.0", 10 | about = "A command-line text manipulation utility", 11 | name = "Text Manipulation Utility" 12 | )] 13 | pub struct Cli { 14 | /// Turn debugging information on. 15 | #[arg(short, long, action = clap::ArgAction::Count)] 16 | debug: u8, 17 | /// Find and Replace commands. 18 | #[command(subcommand)] 19 | pub command: Option 20 | } 21 | 22 | #[derive(Subcommand, Debug)] 23 | pub enum Commands { 24 | /// Subcommand for handling find operations. 25 | Find(FindCommands), 26 | /// Subcommand for handling replace operations. 27 | Replace(ReplaceCommands), 28 | } 29 | 30 | /// Represents find-related commands. 31 | #[derive(Debug, Args)] 32 | pub struct FindCommands { 33 | /// Sets the input file to process 34 | #[clap(short = 'i', long = "input")] 35 | pub input: Option, 36 | /// Sets the pattern to find. 37 | #[clap(short = 'p', long = "pattern")] 38 | pub pattern: Option, 39 | } 40 | 41 | /// Represents repalce-related commands. 42 | #[derive(Debug, Args)] 43 | pub struct ReplaceCommands { 44 | /// Sets the input file to process 45 | #[clap(short = 'i', long = "input")] 46 | pub input: Option, 47 | /// Sets the pattern to find. 48 | #[clap(short = 'p', long = "pattern")] 49 | pub pattern: Option, 50 | /// Sets the replacement text. 51 | #[clap(short = 'r', long = "replace")] 52 | pub replace: Option, 53 | } 54 | 55 | fn read_file_to_string(file_path: &str) -> io::Result { 56 | let mut file = File::open(file_path)?; 57 | let mut contents = String::new(); 58 | file.read_to_string(&mut contents)?; 59 | 60 | Ok(contents) 61 | } 62 | 63 | fn find_and_replace(content: &mut String, pattern: &str, replacement: &str) { 64 | *content = content.replace(pattern, replacement); 65 | } 66 | 67 | fn write_string_to_file(file_path: &str, content: &str) -> io::Result<()> { 68 | let mut file = File::create(file_path)?; 69 | file.write_all(content.as_bytes())?; 70 | 71 | Ok(()) 72 | } 73 | 74 | fn main() -> io::Result<()> { 75 | let args = Cli::parse(); 76 | let mut input_content = "".to_string(); 77 | let mut pattern_to_find = "".to_string(); 78 | let mut replacement_text = "".to_string(); 79 | let mut input_file_path = "".to_string(); 80 | 81 | match args.command { 82 | Some(Commands::Find(command)) => { 83 | if let Some(input) = &command.input { 84 | input_content = read_file_to_string(input)?; 85 | println!("Input file content: {:?}", input_content); 86 | } else { 87 | println!("Please provide a file name."); 88 | } 89 | if let Some(pattern) = &command.pattern { 90 | pattern_to_find = pattern.clone(); 91 | println!("Pattern: {:?}", pattern); 92 | } else { 93 | println!("Please provide a pattern."); 94 | } 95 | } 96 | Some(Commands::Replace(command)) => { 97 | if let Some(input) = &command.input { 98 | input_file_path = input.to_string(); 99 | input_content = read_file_to_string(input)?; 100 | println!("Input file content: {:?}", input_content); 101 | } else { 102 | println!("Please provide a file name."); 103 | } 104 | if let Some(pattern) = &command.pattern { 105 | pattern_to_find = pattern.clone(); 106 | println!("Pattern: {:?}", pattern_to_find); 107 | } else { 108 | println!("Please provide a pattern."); 109 | } 110 | if let Some(replace) = &command.replace { 111 | replacement_text = replace.clone(); 112 | println!("Replacement text: {:?}", replacement_text); 113 | } else { 114 | println!("Please provide a replacement text."); 115 | } 116 | } 117 | None => println!("Unknown command. Use '--help' for usage instructions.") 118 | }; 119 | 120 | println!("File Content Before: {:?}", input_content); 121 | find_and_replace(&mut input_content, &pattern_to_find, &replacement_text); 122 | 123 | write_string_to_file(&input_file_path, &input_content)?; 124 | 125 | input_content = read_file_to_string(&input_file_path)?; 126 | println!("File Content After: {:?}", input_content); 127 | Ok(()) 128 | } -------------------------------------------------------------------------------- /chapter-8/8-case-insensitive-search/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "case-insensitive-search" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | regex = "1.10.2" 11 | -------------------------------------------------------------------------------- /chapter-8/8-case-insensitive-search/file.txt: -------------------------------------------------------------------------------- 1 | Hello Rust 2 | -------------------------------------------------------------------------------- /chapter-8/8-case-insensitive-search/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | use clap::{Parser, Subcommand}; 3 | use std::fs::File; 4 | use std::io::{self, Read, Write}; 5 | use regex::Regex; 6 | 7 | #[derive(Parser, Debug)] 8 | #[command( 9 | author = "Mahmoud Harmouch", 10 | version = "1.0", 11 | about = "A command-line text manipulation utility", 12 | name = "Text Manipulation Utility" 13 | )] 14 | pub struct Cli { 15 | /// Turn debugging information on. 16 | #[arg(short, long, action = clap::ArgAction::Count)] 17 | debug: u8, 18 | /// Find and Replace commands. 19 | #[command(subcommand)] 20 | pub command: Option 21 | } 22 | 23 | #[derive(Subcommand, Debug)] 24 | pub enum Commands { 25 | /// Subcommand for handling find operations. 26 | Find(FindCommands), 27 | /// Subcommand for handling replace operations. 28 | Replace(ReplaceCommands), 29 | } 30 | 31 | /// Represents find-related commands. 32 | #[derive(Debug, Args)] 33 | pub struct FindCommands { 34 | /// Sets the input file to process 35 | #[clap(short = 'i', long = "input")] 36 | pub input: Option, 37 | /// Sets the pattern to find. 38 | #[clap(short = 'p', long = "pattern")] 39 | pub pattern: Option, 40 | } 41 | 42 | /// Represents repalce-related commands. 43 | #[derive(Debug, Args)] 44 | pub struct ReplaceCommands { 45 | /// Sets the input file to process 46 | #[clap(short = 'i', long = "input")] 47 | pub input: Option, 48 | /// Sets the pattern to find. 49 | #[clap(short = 'p', long = "pattern")] 50 | pub pattern: Option, 51 | /// Sets the replacement text. 52 | #[clap(short = 'r', long = "replace")] 53 | pub replace: Option, 54 | /// Perform a case-insensitive search and replace. 55 | #[clap(short = 'c', long = "ignore-case")] 56 | pub ignore_case: bool, 57 | 58 | } 59 | 60 | fn read_file_to_string(file_path: &str) -> io::Result { 61 | let mut file = File::open(file_path)?; 62 | let mut contents = String::new(); 63 | file.read_to_string(&mut contents)?; 64 | 65 | Ok(contents) 66 | } 67 | 68 | fn find_and_replace(content: &mut String, pattern: &str, replacement: &str, ignore_case: bool) { 69 | let regex = if ignore_case { 70 | Regex::new(&format!(r"(?i){}", pattern)).unwrap() 71 | } else { 72 | Regex::new(pattern).unwrap() 73 | }; 74 | 75 | *content = regex.replace_all(content, replacement).to_string(); 76 | } 77 | 78 | fn write_string_to_file(file_path: &str, content: &str) -> io::Result<()> { 79 | let mut file = File::create(file_path)?; 80 | file.write_all(content.as_bytes())?; 81 | 82 | Ok(()) 83 | } 84 | 85 | fn main() -> io::Result<()> { 86 | let args = Cli::parse(); 87 | let mut input_content = "".to_string(); 88 | let mut _pattern_to_find = "".to_string(); 89 | let mut replacement_text = "".to_string(); 90 | let mut input_file_path = "".to_string(); 91 | let mut _ignore_case = false; 92 | 93 | match args.command { 94 | Some(Commands::Find(command)) => { 95 | if let Some(input) = &command.input { 96 | input_content = read_file_to_string(input)?; 97 | println!("Input file content: {:?}", input_content); 98 | } else { 99 | println!("Please provide a file name."); 100 | } 101 | if let Some(pattern) = &command.pattern { 102 | _pattern_to_find = pattern.clone(); 103 | println!("Pattern: {:?}", pattern); 104 | } else { 105 | println!("Please provide a pattern."); 106 | } 107 | } 108 | Some(Commands::Replace(command)) => { 109 | if let Some(input) = &command.input { 110 | input_file_path = input.to_string(); 111 | input_content = read_file_to_string(input)?; 112 | println!("Input file content: {:?}", input_content); 113 | } else { 114 | println!("Please provide a file name."); 115 | } 116 | if let Some(pattern) = &command.pattern { 117 | _pattern_to_find = pattern.clone(); 118 | println!("Pattern: {:?}", _pattern_to_find); 119 | } else { 120 | println!("Please provide a pattern."); 121 | } 122 | if let Some(replace) = &command.replace { 123 | replacement_text = replace.clone(); 124 | println!("Replacement text: {:?}", replacement_text); 125 | } else { 126 | println!("Please provide a replacement text."); 127 | } 128 | _ignore_case = command.ignore_case; 129 | println!("Ignore case: {:?}", _ignore_case); 130 | println!("File Content Before: {:?}", input_content); 131 | find_and_replace(&mut input_content, &_pattern_to_find, &replacement_text, _ignore_case); 132 | 133 | write_string_to_file(&input_file_path, &input_content)?; 134 | 135 | input_content = read_file_to_string(&input_file_path)?; 136 | println!("File Content After: {:?}", input_content); 137 | } 138 | None => println!("Unknown command. Use '--help' for usage instructions.") 139 | }; 140 | 141 | Ok(()) 142 | 143 | } -------------------------------------------------------------------------------- /chapter-8/9-multiple-input-files/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "anstream" 16 | version = "0.6.5" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" 19 | dependencies = [ 20 | "anstyle", 21 | "anstyle-parse", 22 | "anstyle-query", 23 | "anstyle-wincon", 24 | "colorchoice", 25 | "utf8parse", 26 | ] 27 | 28 | [[package]] 29 | name = "anstyle" 30 | version = "1.0.4" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 33 | 34 | [[package]] 35 | name = "anstyle-parse" 36 | version = "0.2.3" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 39 | dependencies = [ 40 | "utf8parse", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-query" 45 | version = "1.0.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 48 | dependencies = [ 49 | "windows-sys", 50 | ] 51 | 52 | [[package]] 53 | name = "anstyle-wincon" 54 | version = "3.0.2" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 57 | dependencies = [ 58 | "anstyle", 59 | "windows-sys", 60 | ] 61 | 62 | [[package]] 63 | name = "clap" 64 | version = "4.4.11" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" 67 | dependencies = [ 68 | "clap_builder", 69 | "clap_derive", 70 | ] 71 | 72 | [[package]] 73 | name = "clap_builder" 74 | version = "4.4.11" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" 77 | dependencies = [ 78 | "anstream", 79 | "anstyle", 80 | "clap_lex", 81 | "strsim", 82 | ] 83 | 84 | [[package]] 85 | name = "clap_derive" 86 | version = "4.4.7" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" 89 | dependencies = [ 90 | "heck", 91 | "proc-macro2", 92 | "quote", 93 | "syn", 94 | ] 95 | 96 | [[package]] 97 | name = "clap_lex" 98 | version = "0.6.0" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" 101 | 102 | [[package]] 103 | name = "colorchoice" 104 | version = "1.0.0" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 107 | 108 | [[package]] 109 | name = "heck" 110 | version = "0.4.1" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 113 | 114 | [[package]] 115 | name = "memchr" 116 | version = "2.6.4" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" 119 | 120 | [[package]] 121 | name = "multiple-input-files" 122 | version = "0.1.0" 123 | dependencies = [ 124 | "clap", 125 | "regex", 126 | ] 127 | 128 | [[package]] 129 | name = "proc-macro2" 130 | version = "1.0.70" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" 133 | dependencies = [ 134 | "unicode-ident", 135 | ] 136 | 137 | [[package]] 138 | name = "quote" 139 | version = "1.0.33" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 142 | dependencies = [ 143 | "proc-macro2", 144 | ] 145 | 146 | [[package]] 147 | name = "regex" 148 | version = "1.10.2" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 151 | dependencies = [ 152 | "aho-corasick", 153 | "memchr", 154 | "regex-automata", 155 | "regex-syntax", 156 | ] 157 | 158 | [[package]] 159 | name = "regex-automata" 160 | version = "0.4.3" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 163 | dependencies = [ 164 | "aho-corasick", 165 | "memchr", 166 | "regex-syntax", 167 | ] 168 | 169 | [[package]] 170 | name = "regex-syntax" 171 | version = "0.8.2" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 174 | 175 | [[package]] 176 | name = "strsim" 177 | version = "0.10.0" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 180 | 181 | [[package]] 182 | name = "syn" 183 | version = "2.0.39" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" 186 | dependencies = [ 187 | "proc-macro2", 188 | "quote", 189 | "unicode-ident", 190 | ] 191 | 192 | [[package]] 193 | name = "unicode-ident" 194 | version = "1.0.12" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 197 | 198 | [[package]] 199 | name = "utf8parse" 200 | version = "0.2.1" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 203 | 204 | [[package]] 205 | name = "windows-sys" 206 | version = "0.52.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 209 | dependencies = [ 210 | "windows-targets", 211 | ] 212 | 213 | [[package]] 214 | name = "windows-targets" 215 | version = "0.52.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 218 | dependencies = [ 219 | "windows_aarch64_gnullvm", 220 | "windows_aarch64_msvc", 221 | "windows_i686_gnu", 222 | "windows_i686_msvc", 223 | "windows_x86_64_gnu", 224 | "windows_x86_64_gnullvm", 225 | "windows_x86_64_msvc", 226 | ] 227 | 228 | [[package]] 229 | name = "windows_aarch64_gnullvm" 230 | version = "0.52.0" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 233 | 234 | [[package]] 235 | name = "windows_aarch64_msvc" 236 | version = "0.52.0" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 239 | 240 | [[package]] 241 | name = "windows_i686_gnu" 242 | version = "0.52.0" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 245 | 246 | [[package]] 247 | name = "windows_i686_msvc" 248 | version = "0.52.0" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 251 | 252 | [[package]] 253 | name = "windows_x86_64_gnu" 254 | version = "0.52.0" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 257 | 258 | [[package]] 259 | name = "windows_x86_64_gnullvm" 260 | version = "0.52.0" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 263 | 264 | [[package]] 265 | name = "windows_x86_64_msvc" 266 | version = "0.52.0" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 269 | -------------------------------------------------------------------------------- /chapter-8/9-multiple-input-files/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multiple-input-files" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.4.11", features = ["derive"] } 10 | regex = "1.10.2" 11 | -------------------------------------------------------------------------------- /chapter-8/9-multiple-input-files/file1.txt: -------------------------------------------------------------------------------- 1 | Hello Rust 2 | -------------------------------------------------------------------------------- /chapter-8/9-multiple-input-files/file2.txt: -------------------------------------------------------------------------------- 1 | Hello Rust 2 | -------------------------------------------------------------------------------- /chapter-8/9-multiple-input-files/file3.txt: -------------------------------------------------------------------------------- 1 | Hello Rust 2 | -------------------------------------------------------------------------------- /chapter-8/9-multiple-input-files/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Args; 2 | use clap::{Parser, Subcommand}; 3 | use std::fs::File; 4 | use std::io::{self, Read, Write}; 5 | use regex::Regex; 6 | 7 | #[derive(Parser, Debug)] 8 | #[command( 9 | author = "Mahmoud Harmouch", 10 | version = "1.0", 11 | about = "A command-line text manipulation utility", 12 | name = "Text Manipulation Utility" 13 | )] 14 | pub struct Cli { 15 | /// Turn debugging information on. 16 | #[arg(short, long, action = clap::ArgAction::Count)] 17 | debug: u8, 18 | /// Find and Replace commands. 19 | #[command(subcommand)] 20 | pub command: Option 21 | } 22 | 23 | #[derive(Subcommand, Debug)] 24 | pub enum Commands { 25 | /// Subcommand for handling find operations. 26 | Find(FindCommands), 27 | /// Subcommand for handling replace operations. 28 | Replace(ReplaceCommands), 29 | } 30 | 31 | /// Represents find-related commands. 32 | #[derive(Debug, Args)] 33 | pub struct FindCommands { 34 | /// Sets the input file to process 35 | #[clap(short = 'i', long = "input", num_args = 1.., value_delimiter = ' ')] 36 | pub input: Option>, 37 | /// Sets the pattern to find. 38 | #[clap(short = 'p', long = "pattern")] 39 | pub pattern: Option, 40 | } 41 | 42 | /// Represents repalce-related commands. 43 | #[derive(Debug, Args)] 44 | pub struct ReplaceCommands { 45 | /// Sets the input file to process 46 | #[clap(short = 'i', long = "input", num_args = 1.., value_delimiter = ' ')] 47 | pub input: Option>, 48 | /// Sets the pattern to find. 49 | #[clap(short = 'p', long = "pattern")] 50 | pub pattern: Option, 51 | /// Sets the replacement text. 52 | #[clap(short = 'r', long = "replace")] 53 | pub replace: Option, 54 | /// Perform a case-insensitive search and replace. 55 | #[clap(short = 'c', long = "ignore-case")] 56 | pub ignore_case: bool, 57 | 58 | } 59 | 60 | fn read_file_to_string(file_path: &str) -> io::Result { 61 | let mut file = File::open(file_path)?; 62 | let mut contents = String::new(); 63 | file.read_to_string(&mut contents)?; 64 | 65 | Ok(contents) 66 | } 67 | 68 | fn find_and_replace(content: &mut String, pattern: &str, replacement: &str, ignore_case: bool) { 69 | let regex = if ignore_case { 70 | Regex::new(&format!(r"(?i){}", pattern)).unwrap() 71 | } else { 72 | Regex::new(pattern).unwrap() 73 | }; 74 | 75 | *content = regex.replace_all(content, replacement).to_string(); 76 | } 77 | 78 | fn write_string_to_file(file_path: &str, content: &str) -> io::Result<()> { 79 | let mut file = File::create(file_path)?; 80 | file.write_all(content.as_bytes())?; 81 | 82 | Ok(()) 83 | } 84 | 85 | fn main() -> io::Result<()> { 86 | let args = Cli::parse(); 87 | let mut input_files: Vec = vec!["".to_string(),]; 88 | let mut pattern_to_find = "".to_string(); 89 | let mut replacement_text = "".to_string(); 90 | let mut _ignore_case = false; 91 | 92 | match args.command { 93 | Some(Commands::Find(command)) => { 94 | if let Some(input) = &command.input { 95 | input_files = input.to_vec(); 96 | } else { 97 | println!("Please provide a file name."); 98 | } 99 | if let Some(pattern) = &command.pattern { 100 | pattern_to_find = pattern.clone(); 101 | println!("Pattern: {:?}", pattern); 102 | } else { 103 | println!("Please provide a pattern."); 104 | } 105 | 106 | for input_file_path in input_files { 107 | let mut input_content = read_file_to_string(&input_file_path)?; 108 | 109 | find_and_replace(&mut input_content, &pattern_to_find, "", _ignore_case); 110 | 111 | println!("Found Content: {:?}", input_content); 112 | } 113 | } 114 | Some(Commands::Replace(command)) => { 115 | if let Some(input) = &command.input { 116 | input_files = input.to_vec(); 117 | } else { 118 | println!("Please provide a file name."); 119 | } 120 | if let Some(pattern) = &command.pattern { 121 | pattern_to_find = pattern.clone(); 122 | println!("Pattern: {:?}", pattern_to_find); 123 | } else { 124 | println!("Please provide a pattern."); 125 | } 126 | if let Some(replace) = &command.replace { 127 | replacement_text = replace.clone(); 128 | println!("Replacement text: {:?}", replacement_text); 129 | } else { 130 | println!("Please provide a replacement text."); 131 | } 132 | _ignore_case = command.ignore_case; 133 | println!("Ignore case: {:?}", _ignore_case); 134 | for input_file_path in input_files { 135 | let mut input_content = read_file_to_string(&input_file_path)?; 136 | 137 | println!("File Content Before: {:?}", input_content); 138 | find_and_replace(&mut input_content, &pattern_to_find, &replacement_text, _ignore_case); 139 | 140 | // Write the modified content back to the input file 141 | write_string_to_file(&input_file_path, &input_content)?; 142 | 143 | input_content = read_file_to_string(&input_file_path)?; 144 | println!("File Content After: {:?}", input_content); 145 | } 146 | 147 | } 148 | None => println!("Unknown command. Use '--help' for usage instructions.") 149 | }; 150 | 151 | Ok(()) 152 | 153 | } -------------------------------------------------------------------------------- /chapter-9/asynchronous-networking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "asynchronous-networking" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | tokio = { version = "1.35.0", features = ["full"] } 10 | -------------------------------------------------------------------------------- /chapter-9/asynchronous-networking/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::net::TcpListener; 2 | use std::io::{Read, Write}; 3 | 4 | fn main() -> Result<(), Box> { 5 | let listener = TcpListener::bind("0.0.0.0:8080")?; 6 | println!("Sensor server listening on 0.0.0.0:8080"); 7 | 8 | for stream in listener.incoming() { 9 | let mut stream = stream?; 10 | let mut buffer = [0; 1024]; 11 | stream.read(&mut buffer)?; 12 | 13 | // Process sensor data from the remote device 14 | let sensor_data = process_sensor_data(&buffer); 15 | 16 | // Perform device I/O operations with the sensor data 17 | perform_device_io(&sensor_data); 18 | 19 | // Respond to the remote device 20 | stream.write_all(b"Data received and processed.")?; 21 | } 22 | 23 | Ok(()) 24 | } 25 | 26 | fn process_sensor_data(data: &[u8]) -> SensorData { 27 | // Process the received data and convert it into a structured format 28 | // In a real-world scenario, this could involve deserialization and validation 29 | // For simplicity, we assume direct conversion in this example 30 | SensorData::from_bytes(data) 31 | } 32 | 33 | fn perform_device_io(sensor_data: &SensorData) { 34 | // Perform device I/O operations using the sensor data 35 | // This could involve controlling actuators, making decisions, or storing data 36 | // In this example, we perform a hypothetical device I/O operation 37 | // by printing the sensor data 38 | println!("Received sensor data: {:?}", sensor_data); 39 | } 40 | 41 | #[derive(Debug)] 42 | struct SensorData { 43 | // Define the structure for sensor data 44 | } 45 | 46 | impl SensorData { 47 | fn from_bytes(_data: &[u8]) -> SensorData { 48 | // Convert the received bytes into a SensorData instance 49 | // In a real-world application, this might involve deserialization 50 | // and validation of the data. 51 | // In this simplified example, we assume the bytes directly represent 52 | // the sensor data. 53 | SensorData {} 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /chapter-9/binary_file.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/binary_file.bin -------------------------------------------------------------------------------- /chapter-9/binary_output.bin: -------------------------------------------------------------------------------- 1 | Hello -------------------------------------------------------------------------------- /chapter-9/config.json: -------------------------------------------------------------------------------- 1 | {"name":"setting","value":42} -------------------------------------------------------------------------------- /chapter-9/example.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/example.txt -------------------------------------------------------------------------------- /chapter-9/hard_link_to_source.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/hard_link_to_source.txt -------------------------------------------------------------------------------- /chapter-9/input.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/input.txt -------------------------------------------------------------------------------- /chapter-9/large_file.bin: -------------------------------------------------------------------------------- 1 | 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 2 | -------------------------------------------------------------------------------- /chapter-9/locked_file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/locked_file.txt -------------------------------------------------------------------------------- /chapter-9/networking-libraries/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "networking-libraries" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | tokio = { version = "1.35.0", features = ["full"] } 10 | hyper = {version = "0.14.27", features = ["http1", "server", "tcp"]} 11 | -------------------------------------------------------------------------------- /chapter-9/networking-libraries/src/main.rs: -------------------------------------------------------------------------------- 1 | use hyper::service::{make_service_fn, service_fn}; 2 | use hyper::{Body, Request, Response, Server}; 3 | use std::convert::Infallible; 4 | use std::net::SocketAddr; 5 | 6 | async fn device_control(_req: Request) -> Result, Infallible> { 7 | // Implement device control logic here 8 | // This function could process incoming requests to control devices 9 | 10 | Ok(Response::new(Body::from("Device control response"))) 11 | } 12 | 13 | #[tokio::main] 14 | async fn main() -> Result<(), Box> { 15 | let make_svc = make_service_fn(|_conn| { 16 | let svc = service_fn(device_control); 17 | async move { Ok::<_, Infallible>(svc) } 18 | }); 19 | 20 | let addr: SocketAddr = ([127, 0, 0, 1], 8080).into(); 21 | let server = Server::bind(&addr).serve(make_svc); 22 | 23 | println!("Device control server listening on http://127.0.0.1:8080"); 24 | 25 | server.await?; 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /chapter-9/new_file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/new_file.txt -------------------------------------------------------------------------------- /chapter-9/output.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/output.txt -------------------------------------------------------------------------------- /chapter-9/path_to_directory/config.json: -------------------------------------------------------------------------------- 1 | {"name":"setting","value":42} -------------------------------------------------------------------------------- /chapter-9/path_to_directory/new_file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/path_to_directory/new_file.txt -------------------------------------------------------------------------------- /chapter-9/shared_file.txt: -------------------------------------------------------------------------------- 1 | 2 | line 0 3 | line 1 4 | line 2 5 | -------------------------------------------------------------------------------- /chapter-9/source_file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiseaidev/rust-lang-book/b3af2f78bbf4436a59cdac57e96f25988e7fe46c/chapter-9/source_file.txt -------------------------------------------------------------------------------- /chapter-9/symlink_to_target.txt: -------------------------------------------------------------------------------- 1 | target_file.txt -------------------------------------------------------------------------------- /chapter_11/1-basic-test-function/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "basic-test-function" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /chapter_11/1-basic-test-function/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "basic-test-function" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /chapter_11/1-basic-test-function/cobertura.xml: -------------------------------------------------------------------------------- 1 | /home/mahmoud/Desktop/Rust Book/rust-lang-book/chapter_11/1-basic-test-function -------------------------------------------------------------------------------- /chapter_11/1-basic-test-function/src/main.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn test_complex_addition() { 3 | let input_1 = 42; 4 | let input_2 = 58; 5 | 6 | let result = perform_complex_addition(input_1, input_2); 7 | 8 | assert_eq!(result, 100, "The addition result is incorrect."); 9 | } 10 | 11 | fn perform_complex_addition(a: i32, b: i32) -> i32 { 12 | a + b 13 | } 14 | -------------------------------------------------------------------------------- /chapter_11/2-test-modules/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "test-modules" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /chapter_11/2-test-modules/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test-modules" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /chapter_11/2-test-modules/src/main.rs: -------------------------------------------------------------------------------- 1 | mod mod_tests { 2 | #[test] 3 | fn test_addition() { 4 | let input_1 = 42; 5 | let input_2 = 58; 6 | 7 | let result = perform_addition(input_1, input_2); 8 | 9 | assert_eq!(result, 100, "The addition result is incorrect."); 10 | } 11 | 12 | fn perform_addition(a: i32, b: i32) -> i32 { 13 | a + b 14 | } 15 | } -------------------------------------------------------------------------------- /chapter_12/1-building-networked-applications/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "building-networked-applications" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | tokio = { version = "1.35.0", features = ["full"] } 10 | -------------------------------------------------------------------------------- /chapter_12/1-building-networked-applications/src/main.rs: -------------------------------------------------------------------------------- 1 | use tokio::net::TcpListener; 2 | use tokio::io::{AsyncReadExt, AsyncWriteExt}; 3 | 4 | #[tokio::main] 5 | async fn main() { 6 | let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); 7 | println!("Server listening on 127.0.0.1:8080..."); 8 | 9 | while let Ok((mut socket, _)) = listener.accept().await { 10 | println!("Accepted a new connection"); 11 | 12 | tokio::spawn(async move { 13 | let mut buffer = [0; 512]; 14 | socket.read(&mut buffer).await.unwrap(); 15 | 16 | // Convert the received bytes to a string for better readability 17 | let request = String::from_utf8_lossy(&buffer[..]); 18 | println!("Received request:\n{}", request); 19 | 20 | let response = b"HTTP/1.1 200 OK\r\n\r\nHello, Rust!"; 21 | socket.write_all(response).await.unwrap(); 22 | println!("Response sent."); 23 | }); 24 | } 25 | } -------------------------------------------------------------------------------- /chapter_12/2-asynchronous-programming/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "asynchronous-programming" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | reqwest = "0.11.22" 10 | tokio = { version = "1.35.0", features = ["full"] } 11 | -------------------------------------------------------------------------------- /chapter_12/2-asynchronous-programming/src/main.rs: -------------------------------------------------------------------------------- 1 | use reqwest::Client; 2 | 3 | async fn fetch_data() -> Result { 4 | let url = "https://jsonplaceholder.typicode.com/posts"; 5 | 6 | let client = Client::new(); 7 | let response = client.get(url).send().await?; 8 | 9 | let body = response.text().await?; 10 | 11 | Ok(body) 12 | } 13 | 14 | #[tokio::main] 15 | async fn main() { 16 | match fetch_data().await { 17 | Ok(data) => println!("Fetched data: {}", data), 18 | Err(e) => eprintln!("Error fetching data: {}", e), 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter_12/3-asynchronous-tcp-server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "asynchronous-tcp-server" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | tokio = { version = "1.35.0", features = ["full"] } 10 | -------------------------------------------------------------------------------- /chapter_12/3-asynchronous-tcp-server/src/main.rs: -------------------------------------------------------------------------------- 1 | use tokio::net::TcpListener; 2 | use tokio::io::{AsyncReadExt, AsyncWriteExt}; 3 | 4 | async fn handle_async_tcp_client(mut socket: tokio::net::TcpStream) { 5 | let mut buffer = [0; 512]; 6 | let bytes_read = socket.read(&mut buffer).await.unwrap(); 7 | 8 | let request = String::from_utf8_lossy(&buffer[..bytes_read]); 9 | println!("Received asynchronous TCP request: {}", request); 10 | 11 | let response = b"HTTP/1.1 200 OK\r\n\r\nHello, Asynchronous TCP!"; 12 | socket.write_all(response).await.unwrap(); 13 | } 14 | 15 | #[tokio::main] 16 | async fn main() { 17 | let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); 18 | 19 | while let Ok((stream, _)) = listener.accept().await { 20 | tokio::spawn(handle_async_tcp_client(stream)); 21 | } 22 | } -------------------------------------------------------------------------------- /chapter_12/4-handle-http-requests-with-hyper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "handle-http-requests-with-hyper" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | hyper = { version = "0.14.27", features = ["http1", "server", "tcp"] } 10 | tokio = { version = "1.35.0", features = ["full"] } 11 | -------------------------------------------------------------------------------- /chapter_12/4-handle-http-requests-with-hyper/src/main.rs: -------------------------------------------------------------------------------- 1 | use hyper::service::{make_service_fn, service_fn}; 2 | use hyper::{Body, Request, Response, Server}; 3 | 4 | async fn handle_request(_: Request) -> Result, hyper::Error> { 5 | let response = Response::new(Body::from("Hello, Rust Web Server!")); 6 | Ok(response) 7 | } 8 | 9 | #[tokio::main] 10 | async fn main() { 11 | let addr = ([127, 0, 0, 1], 8080).into(); 12 | 13 | let make_service = make_service_fn(|_conn| { 14 | async { Ok::<_, hyper::Error>(service_fn(handle_request)) } 15 | }); 16 | 17 | let server = Server::bind(&addr).serve(make_service); 18 | 19 | println!("Rust Web Server running on http://{}", addr); 20 | 21 | if let Err(e) = server.await { 22 | eprintln!("server error: {}", e); 23 | } 24 | } -------------------------------------------------------------------------------- /chapter_12/file.txt: -------------------------------------------------------------------------------- 1 | line 1 2 | line 2 3 | line 3 4 | -------------------------------------------------------------------------------- /chapter_15/crypto/.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /chapter_15/crypto/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /chapter_15/crypto/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | -------------------------------------------------------------------------------- /chapter_15/crypto/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | cache: cargo 5 | 6 | matrix: 7 | include: 8 | 9 | # Builds with wasm-pack. 10 | - rust: beta 11 | env: RUST_BACKTRACE=1 12 | addons: 13 | firefox: latest 14 | chrome: stable 15 | before_script: 16 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 17 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 18 | - cargo install-update -a 19 | - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f 20 | script: 21 | - cargo generate --git . --name testing 22 | # Having a broken Cargo.toml (in that it has curlies in fields) anywhere 23 | # in any of our parent dirs is problematic. 24 | - mv Cargo.toml Cargo.toml.tmpl 25 | - cd testing 26 | - wasm-pack build 27 | - wasm-pack test --chrome --firefox --headless 28 | 29 | # Builds on nightly. 30 | - rust: nightly 31 | env: RUST_BACKTRACE=1 32 | before_script: 33 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 34 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 35 | - cargo install-update -a 36 | - rustup target add wasm32-unknown-unknown 37 | script: 38 | - cargo generate --git . --name testing 39 | - mv Cargo.toml Cargo.toml.tmpl 40 | - cd testing 41 | - cargo check 42 | - cargo check --target wasm32-unknown-unknown 43 | - cargo check --no-default-features 44 | - cargo check --target wasm32-unknown-unknown --no-default-features 45 | - cargo check --no-default-features --features console_error_panic_hook 46 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 47 | - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" 48 | - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" 49 | 50 | # Builds on beta. 51 | - rust: beta 52 | env: RUST_BACKTRACE=1 53 | before_script: 54 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 55 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 56 | - cargo install-update -a 57 | - rustup target add wasm32-unknown-unknown 58 | script: 59 | - cargo generate --git . --name testing 60 | - mv Cargo.toml Cargo.toml.tmpl 61 | - cd testing 62 | - cargo check 63 | - cargo check --target wasm32-unknown-unknown 64 | - cargo check --no-default-features 65 | - cargo check --target wasm32-unknown-unknown --no-default-features 66 | - cargo check --no-default-features --features console_error_panic_hook 67 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 68 | # Note: no enabling the `wee_alloc` feature here because it requires 69 | # nightly for now. 70 | -------------------------------------------------------------------------------- /chapter_15/crypto/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "crypto" 3 | version = "0.1.0" 4 | authors = ["wiseaidev "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "rlib"] 9 | 10 | [features] 11 | default = ["console_error_panic_hook"] 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2.84" 15 | 16 | # The `console_error_panic_hook` crate provides better debugging of panics by 17 | # logging them with `console.error`. This is great for development, but requires 18 | # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for 19 | # code size when deploying. 20 | console_error_panic_hook = { version = "0.1.7", optional = true } 21 | aes = "0.8.3" 22 | cbc = { version = "0.1.2", features = ["alloc"] } 23 | 24 | [dev-dependencies] 25 | wasm-bindgen-test = "0.3.34" 26 | 27 | [profile.release] 28 | # Tell `rustc` to optimize for small code size. 29 | opt-level = "s" 30 | -------------------------------------------------------------------------------- /chapter_15/crypto/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Mahmoud Harmouch 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /chapter_15/crypto/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

wasm-pack-template

4 | 5 | A template for kick starting a Rust and WebAssembly project using wasm-pack. 6 | 7 |

8 | Build Status 9 |

10 | 11 |

12 | Tutorial 13 | | 14 | Chat 15 |

16 | 17 | Built with 🦀🕸 by The Rust and WebAssembly Working Group 18 |
19 | 20 | ## About 21 | 22 | [**📚 Read this template tutorial! 📚**][template-docs] 23 | 24 | This template is designed for compiling Rust libraries into WebAssembly and 25 | publishing the resulting package to NPM. 26 | 27 | Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other 28 | templates and usages of `wasm-pack`. 29 | 30 | [tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html 31 | [template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html 32 | 33 | ## 🚴 Usage 34 | 35 | ### 🐑 Use `cargo generate` to Clone this Template 36 | 37 | [Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) 38 | 39 | ``` 40 | cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project 41 | cd my-project 42 | ``` 43 | 44 | ### 🛠️ Build with `wasm-pack build` 45 | 46 | ``` 47 | wasm-pack build 48 | ``` 49 | 50 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 51 | 52 | ``` 53 | wasm-pack test --headless --firefox 54 | ``` 55 | 56 | ### 🎁 Publish to NPM with `wasm-pack publish` 57 | 58 | ``` 59 | wasm-pack publish 60 | ``` 61 | 62 | ## 🔋 Batteries Included 63 | 64 | * [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating 65 | between WebAssembly and JavaScript. 66 | * [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) 67 | for logging panic messages to the developer console. 68 | * `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you 69 | 70 | ## License 71 | 72 | Licensed under either of 73 | 74 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 75 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 76 | 77 | at your option. 78 | 79 | ### Contribution 80 | 81 | Unless you explicitly state otherwise, any contribution intentionally 82 | submitted for inclusion in the work by you, as defined in the Apache-2.0 83 | license, shall be dual licensed as above, without any additional terms or 84 | conditions. 85 | -------------------------------------------------------------------------------- /chapter_15/crypto/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | background-color: #1e1e1e; 4 | color: #ffffff; 5 | margin: 0; 6 | padding: 0; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100vh; 11 | } 12 | 13 | .card { 14 | background-color: #333333; 15 | border: 2px solid #61dafb; 16 | border-radius: 8px; 17 | padding: 20px; 18 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 19 | } 20 | 21 | h1 { 22 | color: #61dafb; 23 | } 24 | 25 | textarea { 26 | width: calc(100% - 20px); 27 | padding: 10px; 28 | margin: 10px 0; 29 | border: 1px solid #4fa3d1; 30 | background-color: #333333; 31 | color: #ffffff; 32 | font-size: 16px; 33 | box-sizing: border-box; 34 | border-radius: 4px; 35 | } 36 | button { 37 | padding: 10px; 38 | background-color: #61dafb; 39 | color: #000; 40 | border: none; 41 | cursor: pointer; 42 | font-size: 16px; 43 | transition: background-color 0.3s ease; 44 | border-radius: 4px; 45 | } 46 | 47 | button:hover { 48 | background-color: #4fa3d1; 49 | } 50 | 51 | button:active { 52 | background-color: #307099; 53 | } 54 | -------------------------------------------------------------------------------- /chapter_15/crypto/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cryptography with Rust and WebAssembly 8 | 9 | 10 | 11 |
12 |

Cryptography with Rust and WebAssembly

13 | 17 | 22 | 23 |
24 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /chapter_15/crypto/src/lib.rs: -------------------------------------------------------------------------------- 1 | use aes::cipher::{block_padding::Pkcs7, BlockEncryptMut, KeyIvInit}; 2 | use cbc::Encryptor; 3 | use wasm_bindgen::prelude::*; 4 | 5 | type Aes128CbcEnc = Encryptor; 6 | 7 | #[wasm_bindgen] 8 | pub fn encrypt(data: &[u8], key: &[u8]) -> Vec { 9 | let iv = [0u8; 16]; 10 | let mut buf = Vec::from(data); 11 | let cipher = Aes128CbcEnc::new(key.into(), (&iv).into()); 12 | cipher.encrypt_padded_vec_mut::(&mut buf) 13 | } 14 | -------------------------------------------------------------------------------- /chapter_15/crypto/tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use wasm_bindgen_test::*; 7 | 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn pass() { 12 | assert_eq!(1 + 1, 2); 13 | } 14 | -------------------------------------------------------------------------------- /chapter_15/data-viz/.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /chapter_15/data-viz/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /chapter_15/data-viz/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | -------------------------------------------------------------------------------- /chapter_15/data-viz/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | cache: cargo 5 | 6 | matrix: 7 | include: 8 | 9 | # Builds with wasm-pack. 10 | - rust: beta 11 | env: RUST_BACKTRACE=1 12 | addons: 13 | firefox: latest 14 | chrome: stable 15 | before_script: 16 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 17 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 18 | - cargo install-update -a 19 | - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f 20 | script: 21 | - cargo generate --git . --name testing 22 | # Having a broken Cargo.toml (in that it has curlies in fields) anywhere 23 | # in any of our parent dirs is problematic. 24 | - mv Cargo.toml Cargo.toml.tmpl 25 | - cd testing 26 | - wasm-pack build 27 | - wasm-pack test --chrome --firefox --headless 28 | 29 | # Builds on nightly. 30 | - rust: nightly 31 | env: RUST_BACKTRACE=1 32 | before_script: 33 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 34 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 35 | - cargo install-update -a 36 | - rustup target add wasm32-unknown-unknown 37 | script: 38 | - cargo generate --git . --name testing 39 | - mv Cargo.toml Cargo.toml.tmpl 40 | - cd testing 41 | - cargo check 42 | - cargo check --target wasm32-unknown-unknown 43 | - cargo check --no-default-features 44 | - cargo check --target wasm32-unknown-unknown --no-default-features 45 | - cargo check --no-default-features --features console_error_panic_hook 46 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 47 | - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" 48 | - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" 49 | 50 | # Builds on beta. 51 | - rust: beta 52 | env: RUST_BACKTRACE=1 53 | before_script: 54 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 55 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 56 | - cargo install-update -a 57 | - rustup target add wasm32-unknown-unknown 58 | script: 59 | - cargo generate --git . --name testing 60 | - mv Cargo.toml Cargo.toml.tmpl 61 | - cd testing 62 | - cargo check 63 | - cargo check --target wasm32-unknown-unknown 64 | - cargo check --no-default-features 65 | - cargo check --target wasm32-unknown-unknown --no-default-features 66 | - cargo check --no-default-features --features console_error_panic_hook 67 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 68 | # Note: no enabling the `wee_alloc` feature here because it requires 69 | # nightly for now. 70 | -------------------------------------------------------------------------------- /chapter_15/data-viz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "data-viz" 3 | version = "0.1.0" 4 | authors = ["wiseaidev "] 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "rlib"] 9 | 10 | [features] 11 | default = ["console_error_panic_hook"] 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2.84" 15 | 16 | # The `console_error_panic_hook` crate provides better debugging of panics by 17 | # logging them with `console.error`. This is great for development, but requires 18 | # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for 19 | # code size when deploying. 20 | console_error_panic_hook = { version = "0.1.7", optional = true } 21 | plotters = { version = "0.3.5" } 22 | image = "0.24.8" 23 | 24 | [dev-dependencies] 25 | wasm-bindgen-test = "0.3.34" 26 | 27 | [profile.release] 28 | # Tell `rustc` to optimize for small code size. 29 | opt-level = "s" 30 | -------------------------------------------------------------------------------- /chapter_15/data-viz/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Mahmoud Harmouch 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /chapter_15/data-viz/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

wasm-pack-template

4 | 5 | A template for kick starting a Rust and WebAssembly project using wasm-pack. 6 | 7 |

8 | Build Status 9 |

10 | 11 |

12 | Tutorial 13 | | 14 | Chat 15 |

16 | 17 | Built with 🦀🕸 by The Rust and WebAssembly Working Group 18 |
19 | 20 | ## About 21 | 22 | [**📚 Read this template tutorial! 📚**][template-docs] 23 | 24 | This template is designed for compiling Rust libraries into WebAssembly and 25 | publishing the resulting package to NPM. 26 | 27 | Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other 28 | templates and usages of `wasm-pack`. 29 | 30 | [tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html 31 | [template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html 32 | 33 | ## 🚴 Usage 34 | 35 | ### 🐑 Use `cargo generate` to Clone this Template 36 | 37 | [Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) 38 | 39 | ``` 40 | cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project 41 | cd my-project 42 | ``` 43 | 44 | ### 🛠️ Build with `wasm-pack build` 45 | 46 | ``` 47 | wasm-pack build 48 | ``` 49 | 50 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 51 | 52 | ``` 53 | wasm-pack test --headless --firefox 54 | ``` 55 | 56 | ### 🎁 Publish to NPM with `wasm-pack publish` 57 | 58 | ``` 59 | wasm-pack publish 60 | ``` 61 | 62 | ## 🔋 Batteries Included 63 | 64 | * [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating 65 | between WebAssembly and JavaScript. 66 | * [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) 67 | for logging panic messages to the developer console. 68 | * `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you 69 | 70 | ## License 71 | 72 | Licensed under either of 73 | 74 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 75 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 76 | 77 | at your option. 78 | 79 | ### Contribution 80 | 81 | Unless you explicitly state otherwise, any contribution intentionally 82 | submitted for inclusion in the work by you, as defined in the Apache-2.0 83 | license, shall be dual licensed as above, without any additional terms or 84 | conditions. 85 | -------------------------------------------------------------------------------- /chapter_15/data-viz/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Real-time Data Visualization with Rust and WebAssembly 8 | 32 | 33 | 34 |

Real-time Data Visualization with Plotters

35 |
36 | 37 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /chapter_15/data-viz/src/lib.rs: -------------------------------------------------------------------------------- 1 | use image::RgbImage; 2 | use plotters::prelude::*; 3 | use std::convert::TryInto; 4 | use wasm_bindgen::prelude::*; 5 | 6 | #[wasm_bindgen] 7 | pub fn generate_realtime_chart(x_values: Vec, y_values: Vec) -> Vec { 8 | let data: Vec<(f64, f64)> = x_values.into_iter().zip(y_values).collect(); 9 | 10 | let width = 1600; 11 | let height = 1400; 12 | 13 | let mut image = RgbImage::new(width, height); 14 | 15 | { 16 | let root = BitMapBackend::with_buffer( 17 | &mut image, 18 | (width.try_into().unwrap(), height.try_into().unwrap()), 19 | ) 20 | .into_drawing_area(); 21 | 22 | let _ = root.fill(&WHITE); 23 | 24 | let mut chart = ChartBuilder::on(&root) 25 | .build_cartesian_2d(0.0..10.0, 0.0..100.0) 26 | .unwrap(); 27 | 28 | chart.configure_mesh().draw().unwrap(); 29 | 30 | chart 31 | .draw_series(LineSeries::new(data, &RED).point_size(4)) 32 | .unwrap(); 33 | } 34 | 35 | let mut buffer = Vec::new(); 36 | for pixel in image.pixels() { 37 | buffer.push(pixel.0[0]); 38 | buffer.push(pixel.0[1]); 39 | buffer.push(pixel.0[2]); 40 | } 41 | buffer 42 | } 43 | -------------------------------------------------------------------------------- /chapter_15/data-viz/tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use data_viz::generate_realtime_chart; 7 | use wasm_bindgen_test::*; 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn test_generate_realtime_chart() { 12 | // Sample data 13 | let x_values = vec![1.0, 2.0, 3.0, 4.0, 5.0]; 14 | let y_values = vec![10.0, 20.0, 15.0, 25.0, 30.0]; 15 | 16 | // Call the generate_realtime_chart function 17 | let result = generate_realtime_chart(x_values.clone(), y_values.clone()); 18 | 19 | // You can add more assertions or checks based on your requirements 20 | } 21 | -------------------------------------------------------------------------------- /chapter_15/image-processing/.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /chapter_15/image-processing/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /chapter_15/image-processing/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | -------------------------------------------------------------------------------- /chapter_15/image-processing/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | cache: cargo 5 | 6 | matrix: 7 | include: 8 | 9 | # Builds with wasm-pack. 10 | - rust: beta 11 | env: RUST_BACKTRACE=1 12 | addons: 13 | firefox: latest 14 | chrome: stable 15 | before_script: 16 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 17 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 18 | - cargo install-update -a 19 | - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f 20 | script: 21 | - cargo generate --git . --name testing 22 | # Having a broken Cargo.toml (in that it has curlies in fields) anywhere 23 | # in any of our parent dirs is problematic. 24 | - mv Cargo.toml Cargo.toml.tmpl 25 | - cd testing 26 | - wasm-pack build 27 | - wasm-pack test --chrome --firefox --headless 28 | 29 | # Builds on nightly. 30 | - rust: nightly 31 | env: RUST_BACKTRACE=1 32 | before_script: 33 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 34 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 35 | - cargo install-update -a 36 | - rustup target add wasm32-unknown-unknown 37 | script: 38 | - cargo generate --git . --name testing 39 | - mv Cargo.toml Cargo.toml.tmpl 40 | - cd testing 41 | - cargo check 42 | - cargo check --target wasm32-unknown-unknown 43 | - cargo check --no-default-features 44 | - cargo check --target wasm32-unknown-unknown --no-default-features 45 | - cargo check --no-default-features --features console_error_panic_hook 46 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 47 | - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" 48 | - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" 49 | 50 | # Builds on beta. 51 | - rust: beta 52 | env: RUST_BACKTRACE=1 53 | before_script: 54 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 55 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 56 | - cargo install-update -a 57 | - rustup target add wasm32-unknown-unknown 58 | script: 59 | - cargo generate --git . --name testing 60 | - mv Cargo.toml Cargo.toml.tmpl 61 | - cd testing 62 | - cargo check 63 | - cargo check --target wasm32-unknown-unknown 64 | - cargo check --no-default-features 65 | - cargo check --target wasm32-unknown-unknown --no-default-features 66 | - cargo check --no-default-features --features console_error_panic_hook 67 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 68 | # Note: no enabling the `wee_alloc` feature here because it requires 69 | # nightly for now. 70 | -------------------------------------------------------------------------------- /chapter_15/image-processing/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "image-processing" 3 | version = "0.1.0" 4 | authors = ["wiseaidev "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "rlib"] 9 | 10 | [features] 11 | default = ["console_error_panic_hook"] 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2.84" 15 | 16 | # The `console_error_panic_hook` crate provides better debugging of panics by 17 | # logging them with `console.error`. This is great for development, but requires 18 | # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for 19 | # code size when deploying. 20 | console_error_panic_hook = { version = "0.1.7", optional = true } 21 | image = "0.24.8" 22 | 23 | [dev-dependencies] 24 | wasm-bindgen-test = "0.3.34" 25 | 26 | [profile.release] 27 | # Tell `rustc` to optimize for small code size. 28 | opt-level = "s" 29 | -------------------------------------------------------------------------------- /chapter_15/image-processing/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Mahmoud Harmouch 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /chapter_15/image-processing/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

wasm-pack-template

4 | 5 | A template for kick starting a Rust and WebAssembly project using wasm-pack. 6 | 7 |

8 | Build Status 9 |

10 | 11 |

12 | Tutorial 13 | | 14 | Chat 15 |

16 | 17 | Built with 🦀🕸 by The Rust and WebAssembly Working Group 18 |
19 | 20 | ## About 21 | 22 | [**📚 Read this template tutorial! 📚**][template-docs] 23 | 24 | This template is designed for compiling Rust libraries into WebAssembly and 25 | publishing the resulting package to NPM. 26 | 27 | Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other 28 | templates and usages of `wasm-pack`. 29 | 30 | [tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html 31 | [template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html 32 | 33 | ## 🚴 Usage 34 | 35 | ### 🐑 Use `cargo generate` to Clone this Template 36 | 37 | [Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) 38 | 39 | ``` 40 | cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project 41 | cd my-project 42 | ``` 43 | 44 | ### 🛠️ Build with `wasm-pack build` 45 | 46 | ``` 47 | wasm-pack build 48 | ``` 49 | 50 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 51 | 52 | ``` 53 | wasm-pack test --headless --firefox 54 | ``` 55 | 56 | ### 🎁 Publish to NPM with `wasm-pack publish` 57 | 58 | ``` 59 | wasm-pack publish 60 | ``` 61 | 62 | ## 🔋 Batteries Included 63 | 64 | * [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating 65 | between WebAssembly and JavaScript. 66 | * [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) 67 | for logging panic messages to the developer console. 68 | * `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you 69 | 70 | ## License 71 | 72 | Licensed under either of 73 | 74 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 75 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 76 | 77 | at your option. 78 | 79 | ### Contribution 80 | 81 | Unless you explicitly state otherwise, any contribution intentionally 82 | submitted for inclusion in the work by you, as defined in the Apache-2.0 83 | license, shall be dual licensed as above, without any additional terms or 84 | conditions. 85 | -------------------------------------------------------------------------------- /chapter_15/image-processing/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | background-color: #1e1e1e; 4 | color: #ffffff; 5 | margin: 0; 6 | padding: 0; 7 | display: flex; 8 | flex-direction: column; 9 | align-items: center; 10 | justify-content: center; 11 | height: 100vh; 12 | } 13 | 14 | h1 { 15 | color: #61dafb; 16 | } 17 | 18 | input[type="file"] { 19 | margin: 20px 0; 20 | } 21 | 22 | .container { 23 | display: flex; 24 | box-sizing: border-box; 25 | } 26 | 27 | canvas { 28 | border: 1px solid #333333; 29 | border-radius: 8px; 30 | margin: 20px; 31 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 32 | } 33 | -------------------------------------------------------------------------------- /chapter_15/image-processing/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Image Processing with Rust and WebAssembly 9 | 10 | 11 |

Image Processing with Rust and WebAssembly

12 | 18 |
19 | 25 | 31 |
32 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /chapter_15/image-processing/src/lib.rs: -------------------------------------------------------------------------------- 1 | use image::RgbaImage; 2 | use wasm_bindgen::prelude::*; 3 | 4 | #[wasm_bindgen] 5 | pub fn apply_grayscale(input: Vec, width: u32, height: u32) -> Vec { 6 | // Convert the input RGBA image to Grayscale 7 | let mut img = RgbaImage::from_vec(width, height, input).expect("Invalid image dimensions"); 8 | 9 | for pixel in img.pixels_mut() { 10 | let gray_value = 11 | pixel.0[0] as f32 * 0.299 + pixel.0[1] as f32 * 0.587 + pixel.0[2] as f32 * 0.114; 12 | pixel.0 = [ 13 | gray_value as u8, 14 | gray_value as u8, 15 | gray_value as u8, 16 | pixel.0[3], 17 | ]; 18 | } 19 | 20 | // Convert the Grayscale image back to a flat Vec 21 | let output = img.into_raw(); 22 | output 23 | } 24 | -------------------------------------------------------------------------------- /chapter_15/image-processing/tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use wasm_bindgen_test::*; 7 | 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn pass() { 12 | assert_eq!(1 + 1, 2); 13 | } 14 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | cache: cargo 5 | 6 | matrix: 7 | include: 8 | 9 | # Builds with wasm-pack. 10 | - rust: beta 11 | env: RUST_BACKTRACE=1 12 | addons: 13 | firefox: latest 14 | chrome: stable 15 | before_script: 16 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 17 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 18 | - cargo install-update -a 19 | - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f 20 | script: 21 | - cargo generate --git . --name testing 22 | # Having a broken Cargo.toml (in that it has curlies in fields) anywhere 23 | # in any of our parent dirs is problematic. 24 | - mv Cargo.toml Cargo.toml.tmpl 25 | - cd testing 26 | - wasm-pack build 27 | - wasm-pack test --chrome --firefox --headless 28 | 29 | # Builds on nightly. 30 | - rust: nightly 31 | env: RUST_BACKTRACE=1 32 | before_script: 33 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 34 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 35 | - cargo install-update -a 36 | - rustup target add wasm32-unknown-unknown 37 | script: 38 | - cargo generate --git . --name testing 39 | - mv Cargo.toml Cargo.toml.tmpl 40 | - cd testing 41 | - cargo check 42 | - cargo check --target wasm32-unknown-unknown 43 | - cargo check --no-default-features 44 | - cargo check --target wasm32-unknown-unknown --no-default-features 45 | - cargo check --no-default-features --features console_error_panic_hook 46 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 47 | - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" 48 | - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" 49 | 50 | # Builds on beta. 51 | - rust: beta 52 | env: RUST_BACKTRACE=1 53 | before_script: 54 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 55 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 56 | - cargo install-update -a 57 | - rustup target add wasm32-unknown-unknown 58 | script: 59 | - cargo generate --git . --name testing 60 | - mv Cargo.toml Cargo.toml.tmpl 61 | - cd testing 62 | - cargo check 63 | - cargo check --target wasm32-unknown-unknown 64 | - cargo check --no-default-features 65 | - cargo check --target wasm32-unknown-unknown --no-default-features 66 | - cargo check --no-default-features --features console_error_panic_hook 67 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 68 | # Note: no enabling the `wee_alloc` feature here because it requires 69 | # nightly for now. 70 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mathlikeanim-rs-example" 3 | version = "0.1.0" 4 | authors = ["wiseaidev "] 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "rlib"] 9 | 10 | [dependencies] 11 | async-std = { version="1.12.0", features=["attributes"] } 12 | js-sys = "0.3.68" 13 | lightningcss = "1.0.0-alpha.53" 14 | mathlikeanim-rs = "0.3.2" 15 | once_cell = "1.19.0" 16 | percent-encoding = "2.3.1" 17 | reqwest = "0.11.24" 18 | serde = { version = "1.0.196", features = ["derive"] } 19 | serde-wasm-bindgen = "0.6.3" 20 | svg = "0.15.0" 21 | wasm-bindgen = "0.2.91" 22 | wasm-bindgen-futures = "0.4.41" 23 | web-sys = { version="0.3.68", features=[ 24 | 'CanvasRenderingContext2d', 25 | 'Document', 26 | 'Element', 27 | 'HtmlCanvasElement', 28 | 'Window', 29 | 'ImageData', 30 | 'Headers', 31 | 'Request', 32 | 'RequestInit', 33 | 'RequestMode', 34 | 'Response', 35 | ] } 36 | 37 | [dev-dependencies] 38 | wasm-bindgen-test = "0.3.34" 39 | 40 | [profile.release] 41 | # Tell `rustc` to optimize for small code size. 42 | opt-level = "s" 43 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Mahmoud Harmouch 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

wasm-pack-template

4 | 5 | A template for kick starting a Rust and WebAssembly project using wasm-pack. 6 | 7 |

8 | Build Status 9 |

10 | 11 |

12 | Tutorial 13 | | 14 | Chat 15 |

16 | 17 | Built with 🦀🕸 by The Rust and WebAssembly Working Group 18 |
19 | 20 | ## About 21 | 22 | [**📚 Read this template tutorial! 📚**][template-docs] 23 | 24 | This template is designed for compiling Rust libraries into WebAssembly and 25 | publishing the resulting package to NPM. 26 | 27 | Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other 28 | templates and usages of `wasm-pack`. 29 | 30 | [tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html 31 | [template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html 32 | 33 | ## 🚴 Usage 34 | 35 | ### 🐑 Use `cargo generate` to Clone this Template 36 | 37 | [Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) 38 | 39 | ``` 40 | cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project 41 | cd my-project 42 | ``` 43 | 44 | ### 🛠️ Build with `wasm-pack build` 45 | 46 | ``` 47 | wasm-pack build 48 | ``` 49 | 50 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 51 | 52 | ``` 53 | wasm-pack test --headless --firefox 54 | ``` 55 | 56 | ### 🎁 Publish to NPM with `wasm-pack publish` 57 | 58 | ``` 59 | wasm-pack publish 60 | ``` 61 | 62 | ## 🔋 Batteries Included 63 | 64 | * [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating 65 | between WebAssembly and JavaScript. 66 | * [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) 67 | for logging panic messages to the developer console. 68 | * `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you 69 | 70 | ## License 71 | 72 | Licensed under either of 73 | 74 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 75 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 76 | 77 | at your option. 78 | 79 | ### Contribution 80 | 81 | Unless you explicitly state otherwise, any contribution intentionally 82 | submitted for inclusion in the work by you, as defined in the Apache-2.0 83 | license, shall be dual licensed as above, without any additional terms or 84 | conditions. 85 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | background-color: #1e1e1e; 4 | color: #ffffff; 5 | margin: 0; 6 | padding: 0; 7 | display: flex; 8 | flex-direction: column; 9 | align-items: center; 10 | justify-content: center; 11 | height: 100vh; 12 | } 13 | 14 | .container { 15 | display: flex; 16 | flex-direction: column; 17 | box-sizing: border-box; 18 | } 19 | 20 | canvas { 21 | border: 1px solid #333333; 22 | border-radius: 8px; 23 | margin: 20px; 24 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 25 | } 26 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Mathlikeanim RS with Rust and WebAssembly 9 | 10 | 11 |
12 | 13 | 14 |
15 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /chapter_15/mathlikeanim-rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use mathlikeanim_rs::{ 2 | animations::{create::create, draw_stroke_then_fill::draw_stroke_then_fill}, 3 | objects::{ 4 | plotting::axes::{axes, plot_in_axes, riemann_rectangles_for_plot}, 5 | svg_to_vector::svg_to_vector, 6 | vector_object::{VectorFeatures, VectorObject}, 7 | }, 8 | scene::Scene, 9 | utils::{log, smooth}, 10 | }; 11 | use once_cell::sync::Lazy; 12 | use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; 13 | use reqwest; 14 | use std::error::Error; 15 | use wasm_bindgen::prelude::*; 16 | 17 | static mut SCENE: Lazy = Lazy::new(|| Scene::new(1920, 1080, 60, "")); 18 | 19 | async fn tex2svg(tex: &str) -> Result> { 20 | let url = format!( 21 | "http://localhost:8080/tex2svg?from={}", 22 | percent_encode(tex.as_bytes(), NON_ALPHANUMERIC) 23 | ); 24 | 25 | let response = reqwest::get(&url).await?; 26 | 27 | if response.status().is_success() { 28 | let svg = response.text().await?; 29 | Ok(svg) 30 | } else { 31 | Err(format!("Error Occurred: {}", response.status()).into()) 32 | } 33 | } 34 | 35 | pub async fn tex_to_vector(latex: String) -> VectorFeatures { 36 | let svg = tex2svg(latex.as_str()).await; 37 | return svg_to_vector(svg.unwrap().as_str()).set_stroke_color((1.0, 1.0, 1.0, 1.0), true); 38 | } 39 | 40 | #[wasm_bindgen(start)] 41 | pub async fn start() { 42 | let document = web_sys::window().unwrap().document().unwrap(); 43 | log("Loaded document"); 44 | let canvas = document.get_element_by_id("canvas").unwrap(); 45 | log("Loaded canvas"); 46 | let context = canvas 47 | .dyn_into::() 48 | .unwrap() 49 | .get_context("2d") 50 | .unwrap() 51 | .unwrap() 52 | .dyn_into::() 53 | .unwrap(); 54 | log("Got context"); 55 | let sn = unsafe { &mut SCENE }; 56 | sn.init_context(context); 57 | log("Initialized context"); 58 | let axes = axes( 59 | 0.0, 60 | 10.0, 61 | 1.0, 62 | 0.0, 63 | 10.0, 64 | 1.0, 65 | (960.0, 540.0), 66 | Some(800.0), 67 | Some(800.0), 68 | Some((1.0, 1.0, 1.0, 1.0)), 69 | Some(4.0), 70 | Some("butt"), 71 | Some("miter"), 72 | Some(0), 73 | Some(true), 74 | Some(true), 75 | Some(20.0), 76 | Some(20.0), 77 | Some(true), 78 | Some(true), 79 | None, 80 | ); 81 | sn.add(axes.clone()); 82 | sn.play(vec![draw_stroke_then_fill], vec![0], 60, |t| { 83 | smooth(t, 10.0) 84 | }) 85 | .await; 86 | log("Added axes"); 87 | let plot = plot_in_axes( 88 | |t| t.powi(2) / 10.0, 89 | 0.0, 90 | 10.0, 91 | 0.0, 92 | 10.0, 93 | 0.0, 94 | 10.0, 95 | 0.005, 96 | &axes.clone(), 97 | Some((249.0 / 255.0, 105.0 / 255.0, 14.0 / 255.0, 1.0)), 98 | Some(4.0), 99 | Some("butt"), 100 | Some("miter"), 101 | Some(1), 102 | None, 103 | ); 104 | sn.add(plot.clone()); 105 | sn.play(vec![create], vec![1], 60, |t| smooth(t, 10.0)) 106 | .await; 107 | log("Added plot"); 108 | let riemann_rectangles = riemann_rectangles_for_plot( 109 | |t| t.powi(2) / 10.0, 110 | 0.0, 111 | 10.0, 112 | 0.0, 113 | 10.0, 114 | 1.0, 115 | 0.0, 116 | 10.0, 117 | 10, 118 | &axes, 119 | Some((0.0, 0.0, 0.0, 1.0)), 120 | Some((249.0 / 255.0, 105.0 / 255.0, 14.0 / 255.0, 0.75)), 121 | Some(2.0), 122 | Some("butt"), 123 | Some("miter"), 124 | Some(2), 125 | None, 126 | ); 127 | log(format!( 128 | "Riemann rectangles: {:?}", 129 | riemann_rectangles.subobjects.len() 130 | ) 131 | .as_str()); 132 | sn.add(riemann_rectangles); 133 | sn.add(axes); 134 | sn.play(vec![draw_stroke_then_fill], vec![2], 60, |t| { 135 | smooth(t, 10.0) 136 | }) 137 | .await; 138 | let mut func_tex = tex_to_vector("$$f(x) = \\frac{x^2}{10}$$".to_string()).await; 139 | func_tex = func_tex.scale(150.0 / func_tex.get_height(), true); 140 | func_tex = func_tex.next_to_point((0.0, 0.0), (1.0, 1.0), 20.0, (0.0, 0.0), true); 141 | func_tex = func_tex.set_stroke_color((1.0, 1.0, 1.0, 1.0), true); 142 | func_tex.index = 3; 143 | sn.add(func_tex); 144 | sn.play(vec![draw_stroke_then_fill], vec![3], 60, |t| { 145 | smooth(t, 10.0) 146 | }) 147 | .await; 148 | sn.update(); 149 | } 150 | 151 | #[wasm_bindgen(js_name = changeNRects)] 152 | pub async fn change_n_rects(n_rects: usize) { 153 | let sn = unsafe { &mut SCENE }; 154 | let axes = sn.get_objects_from_indices(vec![0])[&0].clone(); 155 | let riemann_rectangles = riemann_rectangles_for_plot( 156 | |t| t.powi(2) / 10.0, 157 | 0.0, 158 | 10.0, 159 | 0.0, 160 | 10.0, 161 | 1.0, 162 | 0.0, 163 | 10.0, 164 | n_rects, 165 | &axes, 166 | Some((0.0, 0.0, 0.0, 1.0)), 167 | Some((249.0 / 255.0, 105.0 / 255.0, 14.0 / 255.0, 0.75)), 168 | Some(2.0), 169 | Some("butt"), 170 | Some("miter"), 171 | Some(2), 172 | None, 173 | ); 174 | sn.add(riemann_rectangles); 175 | sn.add(axes); 176 | sn.update(); 177 | } 178 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | cache: cargo 5 | 6 | matrix: 7 | include: 8 | 9 | # Builds with wasm-pack. 10 | - rust: beta 11 | env: RUST_BACKTRACE=1 12 | addons: 13 | firefox: latest 14 | chrome: stable 15 | before_script: 16 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 17 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 18 | - cargo install-update -a 19 | - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f 20 | script: 21 | - cargo generate --git . --name testing 22 | # Having a broken Cargo.toml (in that it has curlies in fields) anywhere 23 | # in any of our parent dirs is problematic. 24 | - mv Cargo.toml Cargo.toml.tmpl 25 | - cd testing 26 | - wasm-pack build 27 | - wasm-pack test --chrome --firefox --headless 28 | 29 | # Builds on nightly. 30 | - rust: nightly 31 | env: RUST_BACKTRACE=1 32 | before_script: 33 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 34 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 35 | - cargo install-update -a 36 | - rustup target add wasm32-unknown-unknown 37 | script: 38 | - cargo generate --git . --name testing 39 | - mv Cargo.toml Cargo.toml.tmpl 40 | - cd testing 41 | - cargo check 42 | - cargo check --target wasm32-unknown-unknown 43 | - cargo check --no-default-features 44 | - cargo check --target wasm32-unknown-unknown --no-default-features 45 | - cargo check --no-default-features --features console_error_panic_hook 46 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 47 | - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" 48 | - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" 49 | 50 | # Builds on beta. 51 | - rust: beta 52 | env: RUST_BACKTRACE=1 53 | before_script: 54 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 55 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 56 | - cargo install-update -a 57 | - rustup target add wasm32-unknown-unknown 58 | script: 59 | - cargo generate --git . --name testing 60 | - mv Cargo.toml Cargo.toml.tmpl 61 | - cd testing 62 | - cargo check 63 | - cargo check --target wasm32-unknown-unknown 64 | - cargo check --no-default-features 65 | - cargo check --target wasm32-unknown-unknown --no-default-features 66 | - cargo check --no-default-features --features console_error_panic_hook 67 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 68 | # Note: no enabling the `wee_alloc` feature here because it requires 69 | # nightly for now. 70 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm-rust" 3 | version = "0.1.0" 4 | authors = ["wiseaidev "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "rlib"] 9 | 10 | [features] 11 | default = ["console_error_panic_hook"] 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2.84" 15 | 16 | # The `console_error_panic_hook` crate provides better debugging of panics by 17 | # logging them with `console.error`. This is great for development, but requires 18 | # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for 19 | # code size when deploying. 20 | console_error_panic_hook = { version = "0.1.7", optional = true } 21 | 22 | [dev-dependencies] 23 | wasm-bindgen-test = "0.3.34" 24 | 25 | [profile.release] 26 | # Tell `rustc` to optimize for small code size. 27 | opt-level = "s" 28 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Mahmoud Harmouch 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

wasm-pack-template

4 | 5 | A template for kick starting a Rust and WebAssembly project using wasm-pack. 6 | 7 |

8 | Build Status 9 |

10 | 11 |

12 | Tutorial 13 | | 14 | Chat 15 |

16 | 17 | Built with 🦀🕸 by The Rust and WebAssembly Working Group 18 |
19 | 20 | ## About 21 | 22 | [**📚 Read this template tutorial! 📚**][template-docs] 23 | 24 | This template is designed for compiling Rust libraries into WebAssembly and 25 | publishing the resulting package to NPM. 26 | 27 | Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other 28 | templates and usages of `wasm-pack`. 29 | 30 | [tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html 31 | [template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html 32 | 33 | ## 🚴 Usage 34 | 35 | ### 🐑 Use `cargo generate` to Clone this Template 36 | 37 | [Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) 38 | 39 | ``` 40 | cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project 41 | cd my-project 42 | ``` 43 | 44 | ### 🛠️ Build with `wasm-pack build` 45 | 46 | ``` 47 | wasm-pack build 48 | ``` 49 | 50 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 51 | 52 | ``` 53 | wasm-pack test --headless --firefox 54 | ``` 55 | 56 | ### 🎁 Publish to NPM with `wasm-pack publish` 57 | 58 | ``` 59 | wasm-pack publish 60 | ``` 61 | 62 | ## 🔋 Batteries Included 63 | 64 | * [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating 65 | between WebAssembly and JavaScript. 66 | * [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) 67 | for logging panic messages to the developer console. 68 | * `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you 69 | 70 | ## License 71 | 72 | Licensed under either of 73 | 74 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 75 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 76 | 77 | at your option. 78 | 79 | ### Contribution 80 | 81 | Unless you explicitly state otherwise, any contribution intentionally 82 | submitted for inclusion in the work by you, as defined in the Apache-2.0 83 | license, shall be dual licensed as above, without any additional terms or 84 | conditions. 85 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Web Assembly with Rust 8 | 9 | 10 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use wasm_bindgen::prelude::*; 4 | 5 | #[wasm_bindgen] 6 | extern "C" { 7 | fn alert(s: &str); 8 | } 9 | 10 | #[wasm_bindgen] 11 | pub fn greet() { 12 | alert("Hello, wasm-rust!"); 13 | } 14 | 15 | fn fibonacci(n: u32) -> u32 { 16 | match n { 17 | 0 => 0, 18 | 1 => 1, 19 | _ => fibonacci(n - 1) + fibonacci(n - 2), 20 | } 21 | } 22 | 23 | #[wasm_bindgen] 24 | pub extern "C" fn calculate_fibonacci(n: u32) -> u32 { 25 | fibonacci(n) 26 | } -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/src/utils.rs: -------------------------------------------------------------------------------- 1 | pub fn set_panic_hook() { 2 | // When the `console_error_panic_hook` feature is enabled, we can call the 3 | // `set_panic_hook` function at least once during initialization, and then 4 | // we will get better error messages if our code ever panics. 5 | // 6 | // For more details see 7 | // https://github.com/rustwasm/console_error_panic_hook#readme 8 | #[cfg(feature = "console_error_panic_hook")] 9 | console_error_panic_hook::set_once(); 10 | } 11 | -------------------------------------------------------------------------------- /chapter_15/my_wasm_project/tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use wasm_bindgen_test::*; 7 | 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn pass() { 12 | assert_eq!(1 + 1, 2); 13 | } 14 | -------------------------------------------------------------------------------- /chapter_15/networking/.appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe 3 | - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly 4 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin 5 | - rustc -V 6 | - cargo -V 7 | 8 | build: false 9 | 10 | test_script: 11 | - cargo test --locked 12 | -------------------------------------------------------------------------------- /chapter_15/networking/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /chapter_15/networking/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | -------------------------------------------------------------------------------- /chapter_15/networking/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | cache: cargo 5 | 6 | matrix: 7 | include: 8 | 9 | # Builds with wasm-pack. 10 | - rust: beta 11 | env: RUST_BACKTRACE=1 12 | addons: 13 | firefox: latest 14 | chrome: stable 15 | before_script: 16 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 17 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 18 | - cargo install-update -a 19 | - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f 20 | script: 21 | - cargo generate --git . --name testing 22 | # Having a broken Cargo.toml (in that it has curlies in fields) anywhere 23 | # in any of our parent dirs is problematic. 24 | - mv Cargo.toml Cargo.toml.tmpl 25 | - cd testing 26 | - wasm-pack build 27 | - wasm-pack test --chrome --firefox --headless 28 | 29 | # Builds on nightly. 30 | - rust: nightly 31 | env: RUST_BACKTRACE=1 32 | before_script: 33 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 34 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 35 | - cargo install-update -a 36 | - rustup target add wasm32-unknown-unknown 37 | script: 38 | - cargo generate --git . --name testing 39 | - mv Cargo.toml Cargo.toml.tmpl 40 | - cd testing 41 | - cargo check 42 | - cargo check --target wasm32-unknown-unknown 43 | - cargo check --no-default-features 44 | - cargo check --target wasm32-unknown-unknown --no-default-features 45 | - cargo check --no-default-features --features console_error_panic_hook 46 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 47 | - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" 48 | - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" 49 | 50 | # Builds on beta. 51 | - rust: beta 52 | env: RUST_BACKTRACE=1 53 | before_script: 54 | - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) 55 | - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) 56 | - cargo install-update -a 57 | - rustup target add wasm32-unknown-unknown 58 | script: 59 | - cargo generate --git . --name testing 60 | - mv Cargo.toml Cargo.toml.tmpl 61 | - cd testing 62 | - cargo check 63 | - cargo check --target wasm32-unknown-unknown 64 | - cargo check --no-default-features 65 | - cargo check --target wasm32-unknown-unknown --no-default-features 66 | - cargo check --no-default-features --features console_error_panic_hook 67 | - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook 68 | # Note: no enabling the `wee_alloc` feature here because it requires 69 | # nightly for now. 70 | -------------------------------------------------------------------------------- /chapter_15/networking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "networking" 3 | version = "0.1.0" 4 | authors = ["wiseaidev "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "rlib"] 9 | 10 | [features] 11 | default = ["console_error_panic_hook"] 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2.84" 15 | 16 | # The `console_error_panic_hook` crate provides better debugging of panics by 17 | # logging them with `console.error`. This is great for development, but requires 18 | # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for 19 | # code size when deploying. 20 | console_error_panic_hook = { version = "0.1.7", optional = true } 21 | reqwest = "0.11.23" 22 | wasm-bindgen-futures = "0.4.40" 23 | 24 | [dev-dependencies] 25 | wasm-bindgen-test = "0.3.34" 26 | 27 | [profile.release] 28 | # Tell `rustc` to optimize for small code size. 29 | opt-level = "s" 30 | -------------------------------------------------------------------------------- /chapter_15/networking/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Mahmoud Harmouch 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /chapter_15/networking/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

wasm-pack-template

4 | 5 | A template for kick starting a Rust and WebAssembly project using wasm-pack. 6 | 7 |

8 | Build Status 9 |

10 | 11 |

12 | Tutorial 13 | | 14 | Chat 15 |

16 | 17 | Built with 🦀🕸 by The Rust and WebAssembly Working Group 18 |
19 | 20 | ## About 21 | 22 | [**📚 Read this template tutorial! 📚**][template-docs] 23 | 24 | This template is designed for compiling Rust libraries into WebAssembly and 25 | publishing the resulting package to NPM. 26 | 27 | Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other 28 | templates and usages of `wasm-pack`. 29 | 30 | [tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html 31 | [template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html 32 | 33 | ## 🚴 Usage 34 | 35 | ### 🐑 Use `cargo generate` to Clone this Template 36 | 37 | [Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) 38 | 39 | ``` 40 | cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project 41 | cd my-project 42 | ``` 43 | 44 | ### 🛠️ Build with `wasm-pack build` 45 | 46 | ``` 47 | wasm-pack build 48 | ``` 49 | 50 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 51 | 52 | ``` 53 | wasm-pack test --headless --firefox 54 | ``` 55 | 56 | ### 🎁 Publish to NPM with `wasm-pack publish` 57 | 58 | ``` 59 | wasm-pack publish 60 | ``` 61 | 62 | ## 🔋 Batteries Included 63 | 64 | * [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating 65 | between WebAssembly and JavaScript. 66 | * [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) 67 | for logging panic messages to the developer console. 68 | * `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you 69 | 70 | ## License 71 | 72 | Licensed under either of 73 | 74 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 75 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 76 | 77 | at your option. 78 | 79 | ### Contribution 80 | 81 | Unless you explicitly state otherwise, any contribution intentionally 82 | submitted for inclusion in the work by you, as defined in the Apache-2.0 83 | license, shall be dual licensed as above, without any additional terms or 84 | conditions. 85 | -------------------------------------------------------------------------------- /chapter_15/networking/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | background-color: #1e1e1e; 4 | color: #ffffff; 5 | margin: 0; 6 | padding: 0; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 100vh; 11 | } 12 | 13 | .card { 14 | background-color: #333333; 15 | border: 2px solid #61dafb; 16 | border-radius: 8px; 17 | padding: 20px; 18 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | } 23 | 24 | h1 { 25 | color: #61dafb; 26 | } 27 | 28 | button { 29 | padding: 10px; 30 | background-color: #61dafb; 31 | color: #000; 32 | border: none; 33 | cursor: pointer; 34 | font-size: 16px; 35 | margin-top: 10px; 36 | transition: background-color 0.3s ease; 37 | border-radius: 4px; 38 | } 39 | 40 | button:hover { 41 | background-color: #4fa3d1; 42 | } 43 | 44 | button:active { 45 | background-color: #307099; 46 | } 47 | 48 | #result { 49 | margin-top: 20px; 50 | padding: 10px; 51 | border: 1px solid #4fa3d1; 52 | background-color: #333333; 53 | color: #ffffff; 54 | font-size: 16px; 55 | border-radius: 4px; 56 | } 57 | -------------------------------------------------------------------------------- /chapter_15/networking/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Request Handling with Rust and WebAssembly 9 | 10 | 11 |
12 |

Request Handling with Rust and WebAssembly

13 | 14 |
15 |
16 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /chapter_15/networking/src/lib.rs: -------------------------------------------------------------------------------- 1 | use reqwest; 2 | use wasm_bindgen::prelude::*; 3 | 4 | async fn perform_get_request(url: &str) -> Result { 5 | let response = reqwest::get(url).await?; 6 | let body = response.text().await?; 7 | Ok(body) 8 | } 9 | 10 | #[wasm_bindgen] 11 | pub async fn get_request(url: &str) -> JsValue { 12 | match perform_get_request(url).await { 13 | Ok(response_body) => JsValue::from_str(&response_body), 14 | Err(error) => JsValue::from_str(&format!("Error: {:?}", error)), 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter_15/networking/tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use wasm_bindgen_test::*; 7 | 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn pass() { 12 | assert_eq!(1 + 1, 2); 13 | } 14 | --------------------------------------------------------------------------------