first commit

This commit is contained in:
Ashborn 2025-12-16 22:10:06 +05:45
commit a66604eb6c
52 changed files with 790 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target

7
Control_Flow/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "Control_Flow"
version = "0.1.0"

6
Control_Flow/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "Control_Flow"
version = "0.1.0"
edition = "2024"
[dependencies]

3
Control_Flow/README.md Normal file
View file

@ -0,0 +1,3 @@
A non-copy type is a type that can't be duplicated smply by copying its bits.
1. when you assign or pass a non-copy type, owenership is moved, not duplicated
2. After a move, you can no longer use the original valu, unless you explicity clone it back

60
Control_Flow/src/main.rs Normal file
View file

@ -0,0 +1,60 @@
fn main() {
/*
In rust, Control flow is how your program makes decisions and executes code conditionally or repeatedly.
*/
//1. If Expression
println!("if expression");
let mut num = 5;
if num < 15 {
println!("the {} is lesser than 15", num);
} else if num == 5 {
println!("the {} is 5", num);
} else {
println!("the number is prolly greater than 15")
}
//2. match expression => generally its like a switch in other language, but more powerful and exhaustive
println!("match expression");
match num {
1 => println!("one"),
2 | 3 => println!("two or three"),
5 => println!("five"),
4..=10 => println!("between 4 and 10"), //from start to end-1 but if =, then end is given there
_ => println!("Something else"), //default
}
//3.loop => infinite, can break manually
println!("looping");
loop {
num += 1;
if num == 10 {
break;
}
println!("loop count: {}", num);
}
// 4. while loop -> loops while the conditions is true only
println!("while loop");
while num != 0 {
println!("{}", num);
num -= 1;
}
//for looping
println!("for looping");
let arr = [3, 4, 5, 6, 1, 2, 34, 6, 78];
for i in arr.iter() {
println!("{}", i);
}
for i in 0..arr.len() {
println!("{}", arr[i]);
}
/*
using the array or arra.iter() depends, the use of iter is just for read, that can be reused
and doesnt consumes array and is the refrence actually, but without it you have full control
and is completely reverse of the iter
*/
}

7
Enums/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "Enums"
version = "0.1.0"

6
Enums/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "Enums"
version = "0.1.0"
edition = "2024"
[dependencies]

5
Enums/README.md Normal file
View file

@ -0,0 +1,5 @@
# benefits of Enums with match:
- compiler ensures all variants are handled
- clean and readable code
- can include data directly in the enum

35
Enums/src/main.rs Normal file
View file

@ -0,0 +1,35 @@
// An enum defines a type by enumerating its possible values. EAch variant can optionally carry
// data
enum Message {
Quit, // this is no data
Move {
//structure
x: i32,
y: i32,
},
Write(String), // string that can be written
ChangeColor(i32, i32, i32), // three integers, for the rgb
}
fn main() {
let m1 = Message::Move { x: 1, y: 2 };
let m2 = Message::Quit;
let m3 = Message::Write(String::from("safal lama"));
let m4 = Message::ChangeColor(255, 0, 0);
handle(m1);
handle(m2);
handle(m3);
handle(m4);
}
fn handle(msg: Message) {
match msg {
Message::Quit => println!("quit message received"),
Message::Move { x, y } => println!("moving ({}, {})", x, y),
Message::Write(txt) => println!("message: {}", txt),
Message::ChangeColor(r, g, b) => println!("Color: ({},{},{})", r, g, b),
}
}

64
README.md Normal file
View file

@ -0,0 +1,64 @@
## 🟢 Beginner Level
- [x] 1. Introduction to Rust & Installation
- [x] 2. Cargo and Crates
- [x] 3. Variables and Mutability
- [x] 4. Data Types
- [x] 4.5 Advanced => Strings, Array
- [x] 4.6 Advanced => Tuples
- [x] 4.7 Advanced => Vectors
- [x] 4.8 Advanced => Hashmaps
- [x] 5. Functions
- [x] 6. Control Flow (`if`, `match`, loops)
- [] 7. Ownership
- [] 8. References and Borrowing
- [] 9. Slices
- [] 10. Structs
- [] 11. Enums and Pattern Matching
- [] 12. `Option` and `Result`
- [] 13. Collections (`Vec`, `HashMap`, etc.)
- [] 14. Error Handling
- [] 15. Modules
- [ ] 15.1. File Structure
- [ ] 16. Packages, Crates, and Modules
- [ ] 17. Common Macros (`println!`, `dbg!`, `vec!`)
---
## 🟡 Intermediate Level
- [ ] 18. Traits and Trait Bounds
- [ ] 19. Generics
- [ ] 20. Lifetimes
- [ ] 21. Closures and Iterators
- [ ] 22. Smart Pointers (`Box`, `Rc`, `RefCell`)
- [ ] 23. Interior Mutability
- [ ] 24. Concurrency and Multithreading
- [ ] 25. Channels and Message Passing
- [ ] 26. Async Programming with `async/await`
- [ ] 27. Crates like `tokio`, `async-std`
- [ ] 28. Testing (`#[test]`, test modules)
- [ ] 29. Workspaces
- [ ] 30. Error Handling with `thiserror`, `anyhow`
---
## 🔵 Advanced Level
- [ ] 31. Procedural Macros
- [ ] 32. Unsafe Rust
- [ ] 33. FFI (Foreign Function Interface)
- [ ] 34. Advanced Lifetimes and HRTBs
- [ ] 35. Zero-Cost Abstractions
- [ ] 36. Pinning and `Unpin`
- [ ] 37. Custom Smart Pointers
- [ ] 38. Writing DSLs with Macros
- [ ] 39. Trait Objects and Dynamic Dispatch
- [ ] 40. Memory Layout and Alignment
- [ ] 41. Embedded Systems in Rust
- [ ] 42. Writing Web Servers (`actix-web`, `warp`, `axum`)
- [ ] 43. Building CLIs with `clap`, `structopt`
- [ ] 44. Writing Libraries and Publishing to `crates.io`
- [ ] 45. Performance Optimization & Benchmarking
- [ ] 46. Compiler Plugins and MIR (Mid-level IR)

7
Structs/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "Structs"
version = "0.1.0"

6
Structs/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "Structs"
version = "0.1.0"
edition = "2024"
[dependencies]

50
Structs/src/main.rs Normal file
View file

@ -0,0 +1,50 @@
//Struct [Structure] is a custom data type that lets you group related values of different types
//under one name.
struct Person{
name: String,
age: i32
}
//structs with no fiels = unit like Structs
// struct Anime;
impl Person {
fn greet(&self){
println!("Hello, {}!", self.name);
}
fn new(name: &str)->Person{
Person { name: String::from(name),
age: 0
}
}
}
fn main() {
let mut person = Person{
name: String::from("safal lama"),
age: 21
};
person.age+=1;
let fav = Person {
name: String::from("aur"),
..person
};
println!("{}, {}", fav.name, fav.age);
// let m = Anime;
println!("{} is {} yrs old", person.name, person.age);
let a = Person::new("Safal");
a.greet();
}

7
collections/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "collections"
version = "0.1.0"

6
collections/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "collections"
version = "0.1.0"
edition = "2024"
[dependencies]

32
collections/src/main.rs Normal file
View file

@ -0,0 +1,32 @@
//collections are data structures provided by the standard library that store multiple values. They
//are more flexible than arrays and tuples, especially when the size or contents of the collectoin
//are not knows at compile tiem.
use std::collections::HashMap;
fn main() {
//vector
let mut numbers = vec![1,2,3];
numbers.pop();
println!("{:?}", numbers);
//hasmap
let mut scores = HashMap::new();
scores.insert("alice", 1);
if let Some(s) = scores.get("alice"){ //key is case sensitive
println!("{}", s);
}
for val in &numbers{
println!("{}", val);
}
}
//when to use what?
//random access by index = vector
//fast insertin and removal = vecDeque<T>
//need sorted keys = BTreeMap<k,v>
//set of unique items = hasset<t>
//prioirty queue = BinaryHeap<t>

7
datatypes/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "datatypes"
version = "0.1.0"

6
datatypes/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "datatypes"
version = "0.1.0"
edition = "2024"
[dependencies]

12
datatypes/src/general.rs Normal file
View file

@ -0,0 +1,12 @@
pub fn static_variables() {
//integer
let a: i32 = 4;
//float
let pi: f64 = 3.14;
//boolean
let iscorrect: bool = true;
//char
let c: char = 'A';
println!("{}:{}:{}:{}", a, pi, iscorrect, c);
}

22
datatypes/src/hashmap.rs Normal file
View file

@ -0,0 +1,22 @@
use std::collections::HashMap;
pub fn hashmapf() {
/*
in rust, HashMap are the data types which can store according to the key value pair
*/
let mut scores = HashMap::new();
scores.insert("blue", 10);
scores.insert("red", 100);
println!("Blue: {:?}", scores.get("blue"));
match scores.get("red") {
Some(x) => println!("Red => {}", x),
None => println!("error"),
}
//for removing
scores.remove("blue");
for (key, value) in &scores {
println!("{} => {}", key, value);
}
}

12
datatypes/src/main.rs Normal file
View file

@ -0,0 +1,12 @@
mod general;
// mod string_array;
// mod tuples;
// mod vectors;
//mod hashmap;
fn main() {
general::static_variables();
// string_array::s_a();
// tuples::tuples();
// vectors::vectors();
// hashmap::hashmapf();
}

View file

@ -0,0 +1,26 @@
pub fn s_a() {
//rust had two main string types
// 1. &str -> String slice which is immutable and usually used when reading static strings or string litreals
let str_slice: &str = "safal lama";
println!("string slice: {}", str_slice);
//2. String-> which is mutalbe and used when you need to modify or build strings at runtime
let mut str_val = String::from("safal");
str_val.push_str("ski");
println!("general String: {}", str_val);
//array-> is fixed size of same data type => stord on stack
let arr = ['a','b','c','d'];
println!("{:?}", arr);
println!("{}", arr[0]);
for i in 0..arr.len(){
print!("{}, ", arr[i]);
}
println!();
for i in arr{
print!("{}, ", i);
}
println!();
}

14
datatypes/src/tuples.rs Normal file
View file

@ -0,0 +1,14 @@
pub fn tuples() {
/*
tuples are the data structure that can store multiple values of different types
*/
let my_tup = (42, 3.14, 'R');
println!("{:?}", my_tup);
println!("{}", my_tup.0);
//tuples can be destructured
let (x, y, z) = my_tup;
println!("destructured: x={}, y = {}, z ={}", x, y, z);
}

29
datatypes/src/vectors.rs Normal file
View file

@ -0,0 +1,29 @@
pub fn vectors() {
/*
in rust vectors Vec<T> are growable, heap allocated arrays that store elements of the same
type. they are part of standard library and are commonly used when you need a dynamically
sized array.
[features]
- vectors are grow or shrink in sized
- elements are stored contiguiously in memory
- they may useful in Dref, index, Intollerator ets traits
*/
//creating a vectors
let mut v: Vec<i32> = Vec::new(); //empty one[must be have to type anotate explictly]
let v1 = vec![1, 2, 3, 45];
println!("{:?}", v1);
//adding elements
v.push(12);
println!("{:?}", v);
//accessing elements specific
println!("{}", v1[0]);
//for fore safety like if index id out of bound to graceful handle stuff we use match
match v1.get(2) {
Some(value) => println!("value: {}", value),
None => println!("no value found at that index"),
}
}

7
erro-handling/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "erro-handling"
version = "0.1.0"

6
erro-handling/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "erro-handling"
version = "0.1.0"
edition = "2024"
[dependencies]

3
erro-handling/README.md Normal file
View file

@ -0,0 +1,3 @@
# for quick prototyping:
- let file = File::open("hello.txt").unwrap(); //panics
- let file = File::open("hello.txt").expect("Failed to open") // custom error

27
erro-handling/src/main.rs Normal file
View file

@ -0,0 +1,27 @@
use std::{fs::File, io::{self, Read}};
//Error handling in Rust is a critical Aspect of writing reliable and robust programs. Rust
//encuorages handling errors explicity and provides two main types
// - panic! macro -> for unrecovable errors
// - Result<T,E> enum -> for recovable errors
fn main() {
//always use panic when something goes wrong that the program cannot continue
// let num = vec![1,2,3];
// println!("{}", num[99]); //panics cus the index is out of bound!
//Result type is used to handle operations that can succeed or fail like file I/O
match read_file("hello.txt"){
Ok(contents)=> println!("{}", contents),
Err(e)=> eprint!("Erro readihg file: {}",e)
}
}
fn read_file(filename: &str)-> Result<String, io::Error>{
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}

7
functions/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "functions"
version = "0.1.0"

6
functions/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "functions"
version = "0.1.0"
edition = "2024"
[dependencies]

20
functions/src/main.rs Normal file
View file

@ -0,0 +1,20 @@
/*
function is a block or reusable code.
defining the function if fn keyword, and every Rust programs starts with this main function.
*/
fn main() {
greet();
println!("{}", multiple(5, 5));
}
fn greet() {
println!("namaste!")
}
/*
[parameterized function]
no type given is directly compliation error, so type annotatin is important
*/
fn multiple(a: i32, b: i32) -> i32 {
a * b
}

7
modules-file/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "modules-file"
version = "0.1.0"

6
modules-file/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "modules-file"
version = "0.1.0"
edition = "2024"
[dependencies]

13
modules-file/src/main.rs Normal file
View file

@ -0,0 +1,13 @@
mod math;
mod meth;
fn main() {
// a module is a way to group related code together. You can define modules inline or sepearte
// file
let sum = math::add(2,3);
println!("{}", sum);
//using that nested meth module
let mult = meth::advanced::mult(4, 5);
println!("{}", mult);
}

3
modules-file/src/math.rs Normal file
View file

@ -0,0 +1,3 @@
pub fn add(a:i32, b:i32)->i32{
return a+b;
}

View file

@ -0,0 +1,3 @@
pub fn mult(i:i32, x:i32)->i32{
return i*x;
}

View file

@ -0,0 +1 @@
pub mod advanced;

7
options-results/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "options-results"
version = "0.1.0"

View file

@ -0,0 +1,6 @@
[package]
name = "options-results"
version = "0.1.0"
edition = "2024"
[dependencies]

View file

@ -0,0 +1,40 @@
fn main() {
//Option and Result are enums used to handle absence of a value and error handling,
//respectively, withoug using null or exceptions
match get_username(1) {
Some(name)=>println!("{}", name),
None => println!("user not found")
}
match safe_divide(23, 2){
Ok(result)=>println!("{}", result),
Err(e)=> println!("{}", e)
}
match safe_divide(23, 0){
Ok(result)=>println!("{}", result),
Err(e)=> println!("{}", e)
}
}
fn get_username(id:u32)->Option<&'static str>{
if id ==1{
Some("Safal")
}else{
None
}
}
fn safe_divide(a:i32, b:i32)->Result<i32, String>{
if b == 0 {
Err("Can't divide by zero".to_string())
}else {
Ok(a/b)
}
}

7
ownership/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "ownership"
version = "0.1.0"

6
ownership/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "ownership"
version = "0.1.0"
edition = "2024"
[dependencies]

51
ownership/src/main.rs Normal file
View file

@ -0,0 +1,51 @@
fn main() {
//ownership in rust is a centrla concept that governs how memory is managed. It ensures memory
//safety without neding a garbage collector.
//- each value in rust has owner
//- when the owner goes out of scope, the value is dropped
//- values can be moved or borrowed, but not both at the same time
let s1= String::from("safal");
let s2 = s1; //ownership moves to s2 from s1
println!("{}", s2);
//now instead of moving, lets borrow
let a1 = String::from("safallama");
safal(&a1);
println!("{}", a1);
let maxxa = String::from("pantimos");
takeownership(maxxa); //after this pulls up, the maxxa is dropped immediatedly
//
//
let maxxa = giveowenrship();
println!("{}", maxxa);
}
fn safal(s: &String){
println!("{}", s);
}
fn takeownership(s:String){
println!("got string{}",s);
}
fn giveowenrship()->String{
return String::from("ifrate");
}

7
r_B/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "r_B"
version = "0.1.0"

6
r_B/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "r_B"
version = "0.1.0"
edition = "2024"
[dependencies]

29
r_B/src/main.rs Normal file
View file

@ -0,0 +1,29 @@
fn main() {
//borrowing => It means to allowing a function or variabe to use a value without taking
//ownership : type:
//- immutable borrowing [read only access]
//- mutable borrowing [read write access]
let s = String::from("hello world");
print_strirng(&s);
let mut s1 = String::from("safal, hi");
change_string(&mut s1);
println!("{}", s1);
//ownership => It means every value in Rust has single owner, the variable responsible for it,
//When ownership changes, the previous owner can no longer use the value
let owner = String::from("pantsu");
let owner1 = owner;
println!("{}", owner1);
}
//borrowing but read only
fn print_strirng(s: &String){
println!("{} borrowed", s);
}
fn change_string(s: &mut String){
s.push_str("!!");
}

7
slices/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "slices"
version = "0.1.0"

6
slices/Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "slices"
version = "0.1.0"
edition = "2024"
[dependencies]

27
slices/src/main.rs Normal file
View file

@ -0,0 +1,27 @@
fn main() {
//slices are a way to reference a contigous sequence of elements in a collection, without
//owning the data. they let you work with parts of arryas, vectors or strings
//- slices are view into collection
//-they don't own the data, just borrow it
//- &[T] for a slice of elements of type T
let arr = [1,2,3,4,5,50];
let slice = &arr[1..4];
println!("{:?}", slice);
//slice of vector
let vec = vec![2,3,4,5];
let slicer = &vec[2..];
println!("{:?}", slicer);
//string slice
let str = String::from("safal lama");
let slc = &str[0..];
println!("{:?}", slc);
//Slices allow safe, efficient access to parts of collections without copying data.
}

7
variables_mutability/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "variables_mutability"
version = "0.1.0"

View file

@ -0,0 +1,6 @@
[package]
name = "variables_mutability"
version = "0.1.0"
edition = "2024"
[dependencies]

View file

@ -0,0 +1,39 @@
fn main() {
//variables by default is unchangable
//let is used to define the variables
let var1 = String::from("safal lama");
println!("default: {}", var1);
//mut is used to create a changable variable
let mut var2 = String::from("this is safal lama");
var2.push_str(". he is a huge fan of goku");
println!("mutable: {}", var2);
//shadowing is a process of redeclaring the variables
let var_shade = 1;
println!("{}", var_shade);
let var_shade = var_shade + 15;
println!("{}", var_shade);
let var_shade = "Safal lama"; //basically we can directly change the type of variable when shadowing
println!("{}", var_shade);
//constants are not changable and they have to be specified with type annotation
const KONST: i32 = 1;
println!("{}", KONST); // use caps for betterment
/*
[mutability and refrence]
only one mutable reference at a time or a multiple inmutable reference, but not both
*/
let mut str1 = String::from("kakarot");
let str2 = &mut str1; //only one mutable as rule
str2.push_str(", i am goku!");
println!("{}", str1);
//[can be multiple]
let strx = &str1;
println!("{}", strx);
/* [note]
The above code will work despite having mutable and inmutable both however, its about lifetime, cause one ends and other begins, if we didnt printed, then it wouldnt have worked.
*/
}