{"id":19261905,"url":"https://github.com/hacksu/intro-to-rust","last_synced_at":"2025-09-11T17:19:22.526Z","repository":{"id":259115464,"uuid":"875300331","full_name":"hacksu/intro-to-rust","owner":"hacksu","description":"Let's talk about Rust!","archived":false,"fork":false,"pushed_at":"2024-10-22T18:31:55.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-11T09:33:04.182Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hacksu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-19T16:05:30.000Z","updated_at":"2024-10-22T18:32:00.000Z","dependencies_parsed_at":"2024-10-22T21:54:40.211Z","dependency_job_id":null,"html_url":"https://github.com/hacksu/intro-to-rust","commit_stats":null,"previous_names":["hacksu/intro-to-rust"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hacksu/intro-to-rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fintro-to-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fintro-to-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fintro-to-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fintro-to-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hacksu","download_url":"https://codeload.github.com/hacksu/intro-to-rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fintro-to-rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274676390,"owners_count":25329274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T19:28:55.904Z","updated_at":"2025-09-11T17:19:22.500Z","avatar_url":"https://github.com/hacksu.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# intro-to-rust\n\nLet's learn some cool thing about Rust!\n\n## Table of Contents\n- [Installing rustup](#installing-rustup)\n- [Updating rustup](#updating-rustup)\n- [Digging into Rust](#digging-into-rust)\n    + [Hello world](#hello-world)\n    + [Interesting language features](#interesting-language-features)\n    + [Nullability](#nullability)\n    + [Error handling](#error-handling)\n- [Let's actually do something now](#let-s-actually-do-something-now)\n    + [Using Cargo](#using-cargo)\n    + [Actually writing code](#actually-writing-code)\n\n## Installing rustup\n\nFirst, we are going to need to install some tools (specifically `rustup`) so we can get the latest version of Rust, as well as build our project.\nHere are the instructions on [how to install rustup](https://www.rust-lang.org/tools/install) for your system.\n\n**NOTE:** For Windows users, you need [MSVC](https://visualstudio.microsoft.com/downloads/) (you should've installed it in CS1) to build a Rust project.\n\n## Updating rustup\n\nOnce we have `rustup` installed. We can run `rustup up` (funny) and update Rust on our system. If you have previously installed Rust, this will probably update it for you. If you just installed Rust, this will just tell you that you're up to date!\n\n## Digging into Rust\n\nAlright, the Rust compiler is installed, let's write some code. \n\n### Hello world\nAll Rust source files end in the `.rs` extension, so we will create a `hello-world.rs` file and then write some code in it.\n\nIn `hello-world.rs`:\n```Rust\nfn main() {\n    println!(\"Hello, world!\");\n}\n```\n\nFirst off, let's get this out of the way. Why is there an `!` in the `println!` function? In Rust, we refer to this as a *macro*. When we write `println!(\"Hello, world!\")` and then compile our code, the compiler takes this `println!` and generates code to \"replace\" it. There are lots of macros in Rust and you can even make your own. `println!` is probably the most common one you will use.\n\nCool. Now that we understand macros, let's build this program. To build it, we just run `rustc hello-world.rs` from the command line. Then it will generate a program that we can run with `./hello-world.exe` or `./hello-world` depending on your operating system.\n\nWhen you run it, you should see this:\n```\nHello, world!\n```\n\nWonderful! We're now super awesome epic Rust programmers!\n\n### Interesting language features\n\nNow that we've written a \"Hello, world!\" program, let's dig in a little more to some of the semantics of Rust.\n\nFirst, let's look at variable definitions. Let's define some variables:\n```Rust\nlet x = 0;\nx = 1; // ERROR! \n```\n\nError? We can't re-assign variables by default in Rust, if you want to make a variable reassignable, you have to mark it was `mut` or mutable:\n```Rust\nlet mut x = 0;\nx = 1; // yay \n```\n\nYou can redefine a non-mutable variable, that looks something like this:\n```Rust\nlet x = 0;\nlet x = 1;\n```\n\nNext, we will look at loops. Take this C++ for-loop:\n```C++\nfor (int i = 0; i \u003c 10; i++) {\n    std::cout \u003c\u003c i \u003c\u003c std::endl;\n}\n```\n\nWe would write the same loop in Rust like:\n```Rust\nfor i in 0..10 {\n    println!(\"{i}\");\n}\n```\n\nRust has a `Range` datatype, which is iterable (you can use a for-loop with it) and can be created with the `from..to` syntax. \n\nYou'll also notice that there aren't parenthesis around the statement in the for-loop. This is actually a very common thing in Rust:\n```Rust\nlet x = 0;\nif x == 1 {\n    println!(\"X is one!\")\n} else if x == 2 {\n    println!(\"X is two!\")\n} else {\n    println!(\"X is something else!\")\n}\n\nwhile x != 0 {\n    // ...\n}\n```\n\nWe also have the `match` keyword, which can be used like a switch statement:\n```Rust\nlet x = 5;\nmatch x {\n    1 =\u003e println!(\"X is one!\"),\n    2..5 =\u003e println!(\"X is 2 to 5!\"),\n    _ =\u003e println!(\"X is some other value!\"),\n}\n```\nor it can be used to evaluate something in line:\n```Rust\nlet boolean = true;\nlet output = match boolean {\n    false =\u003e 0,\n    true =\u003e 1,\n}\n// output will be true\n```\n\n### Borrows\n\nWe actually have no concept of a pointer in Rust. Well... we kind of do,\nit's just a little different. In Rust, we don't create pointers, we borrow\nthe ownership of the dynamic memory when we want to access it. This is where\nour concept of safety comes from. We never leave a pointer dangling or have \ndynamic memory allocated for longer than it needs to.\n\nLet's see an example of a borrow. We have a function:\n```Rust\nfn print_vec(vec: \u0026Vec\u003cu8\u003e){\n    for i in vec {\n        println!(\"{}\", i);\n    }\n}\n\n```\nAnd then we use it in this code.\n```Rust\nlet nums: Vec\u003cu8\u003e = Vec::new(); \nprint_vec(nums); // no borrow???\n\nlet size = nums.len(); // uhh oh, this won't work\n```\n\nIn the code above, we don't borrow ownership of \"nums\" when we pass it to our\nfunction that prints the vector, so the ownership is moved into that scope and\nthen destroyed at the end of the function. This means once the code continues,\nwe cannot access the length of the vector because it no longer exists.\n\nThe proper code would look like:\n```Rust\nlet nums: Vec\u003cu8\u003e = Vec::new(); \nprint_vec(\u0026nums); // borrow!\n\nlet size = nums.len(); // yay!\n```\n\n### Nullability\n\nIn a lot of programming languages, we have the `null` or `nil` (Lua moment) or `nullptr` which allows us to assign a value to null.\n\nRust *does not* have this which is really great for us. Let's take the example of some C++ code:\n```C++\nchar* val = nullptr;\n\n// imagine some crazy code\n\nstd::cout \u003c\u003c *val;\n```\n\nWOW! We just dereferenced null and caused all sorts of problems. Since we can't do that in Rust, we same ourselves from that problem.\n\nIf we wanted to do a \"null\" value in Rust, it would look like this:\n```Rust\nlet mut val: Option\u003cu64\u003e = None; // value is \"null\"\n\n// this will never happen\nif let Some(number) = val {\n    // ..?\n}\n\nval = Some(10);\n\n// this will happen!\nif let Some(number) = val {\n    println!(\"the number is {}\", number);\n}\n\nval = None;\n\n// we can even do this\nmatch val {\n    Some(number) =\u003e println!(\"the number is {}\", number),\n    None =\u003e println!(\"rip, there is no number.\"),\n}\n```\n\nWonderful. No [NullPointerExceptions](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/NullPointerException.html)!\n\n### Error handling\n\nRust provides us with a great `Result` datatype for error handling. Let's write a function that could throw an error:\n```Rust\nfn do_some_work(fail: bool) -\u003e Result\u003cString, String\u003e {\n    \n    if fail {\n        return Err(String::from(\"not yay!\"));\n    }\n\n    Ok(String::from(\"yay!\"))\n}\n```\nand then our main function:\n```Rust\nlet passed = do_some_work(false);\nif let Ok(message) = passed {\n    println!(\"{}\", message)\n}\n\nlet failed = do_some_work(true);\nif let Err(message) = failed {\n    println!(\"{}\", message)\n}\n```\n\nSeems silly here, but it is super powerful in practice. We could even unwrap a Result with `match`:\n```Rust\nlet output = match do_some_work(true) {\n    Ok(message) =\u003e message,\n    Err(message) =\u003e message\n};\nprintln!(\"{}\", output);\n```\nwhere in this case, the `output` variable will contain whatever message was returned, whether it be an `Error` or `Ok`.\n\n## Let's actually do something now\n\nSo now you know a couple of Rust basics. That's great. Maybe we actually do something that is useful now. We're going to build the popular `tree` Linux command.\n\n### Using Cargo\n\nCargo is Rust's package manager. It is super powerful and if you're ever building anything in Rust, you're going to need to use it. Let's make a new Rust project with `cargo new list-files`.\n\nNow if we open that folder up, we will see a `src/` folder with a `main.rs`. We can run the project with `cargo run`.\n\n### Actually writing code\n\nI want to make a tree view, similar to this:\n```\nlist-files/\n├── Cargo.toml\n└── src\n    └── main.rs\n```\n\nThe lesson will continue with us building the command in `list-files/src/main.rs`. The file is heavily commented and I will explain all the code as I write it. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhacksu%2Fintro-to-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhacksu%2Fintro-to-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhacksu%2Fintro-to-rust/lists"}