├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "kvstore" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kvstore" 3 | version = "0.1.0" 4 | authors = ["Ryan Levick "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Intro to Rust 2 | 3 | This is the code for the my series of "Introduction to Rust" streams. You can find the streams on my [YouTube channel](https://www.youtube.com/channel/UCpeX4D-ArTrsqvhLapAHprQ). 4 | 5 | ## Who are these streams for? 6 | 7 | These introductory streams assume no previous knowledge of [the Rust programming language](https://www.rust-lang.org), but they do assume previous experience with programming. If you are new to programming or have not programmed in a long time, this stream may be too advanced for you. 8 | 9 | ## Getting Started 10 | 11 | To follow along with these streams you'll need only a few pre-requisites: 12 | 13 | #### The Rust compiler toolchain and core tooling 14 | 15 | To install the toolchain, first go to [rustup.rs](https://rustup.rs), and follow the instructions. This should install the compiler, Cargo (Rust's build tool), and other things like documentation. 16 | 17 | You can check that this all worked by: 18 | * opening your terminal (PowerShell, cmd.exe, bash, etc. should all work) 19 | * entering `cargo new hello-world` 20 | * changing into the newly created `hello-world` directory 21 | * running `cargo run` 22 | * if you see "Hello, world!" printed to your screen, then everything should be good to go! 23 | 24 | **Note**: If you are on Windows you will need to install the [Visual C++ build tools](https://visualstudio.microsoft.com/downloads/?WT.mc_id=rust-0000-rylevick#build-tools-for-visual-studio-2019) which includes the MSVC linker which Rust uses. 25 | 26 | #### An Editor 27 | 28 | You can write Rust in an editor of your choice, but for this stream we're using VS Code along with the [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer&WT.mc_id=rust-0000-rylevick) extension. If you're using VS Code, we recommend using this extension over the soon-to-be-deprecated RLS extension. 29 | 30 | ## Asking Questions 31 | 32 | Feel free to leave questions about the contents of the stream as [issues in this repository](https://github.com/rylev/intro-to-rust-streams/issues/new) or as comments on the YouTube videos. I will do my best to answer them. 33 | 34 | ## Additional Resources 35 | 36 | * [The Book](https://doc.rust-lang.org/book/): _The_ resource for learning Rust 37 | * [Rust by Example](https://doc.rust-lang.org/rust-by-example/): Learning Rust by going through examples 38 | * [Rustlings](https://github.com/rust-lang/rustlings): Learn Rust interactively in your terminal -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | fn main() { 4 | let mut arguments = std::env::args().skip(1); 5 | let key = arguments.next().expect("Key was not there"); 6 | let value = arguments.next().unwrap(); 7 | println!("The key is '{}' and the value is '{}'", key, value); 8 | 9 | let mut database = Database::new().expect("Creating db failed"); 10 | database.insert(key.to_uppercase(), value.clone()); 11 | database.insert(key, value); 12 | match database.flush() { 13 | Ok(()) => println!("YAY!"), 14 | Err(err) => println!("OH NOS! Error! {}", err), 15 | } 16 | } 17 | 18 | struct Database { 19 | map: HashMap, 20 | flush: bool, 21 | } 22 | 23 | impl Database { 24 | fn new() -> Result { 25 | let mut map = HashMap::new(); 26 | let contents = std::fs::read_to_string("kv.db")?; 27 | for line in contents.lines() { 28 | let mut chunks = line.splitn(2, '\t'); 29 | let key = chunks.next().expect("No key!"); 30 | let value = chunks.next().expect("No value!"); 31 | map.insert(key.to_owned(), value.to_owned()); 32 | } 33 | Ok(Database { map, flush: false }) 34 | } 35 | 36 | fn insert(&mut self, key: String, value: String) { 37 | self.map.insert(key, value); 38 | } 39 | 40 | fn flush(&self) -> std::io::Result<()> { 41 | do_flush(&self) 42 | } 43 | } 44 | 45 | impl Drop for Database { 46 | fn drop(&mut self) { 47 | if !self.flush { 48 | let _ = do_flush(self); 49 | } 50 | } 51 | } 52 | 53 | fn do_flush(database: &Database) -> std::io::Result<()> { 54 | println!("Do flush called"); 55 | let mut contents = String::new(); 56 | for (key, value) in &database.map { 57 | contents.push_str(key); 58 | contents.push('\t'); 59 | contents.push_str(&&&&value); 60 | contents.push('\n'); 61 | } 62 | std::fs::write("kv.db", contents) 63 | } 64 | --------------------------------------------------------------------------------