diff --git a/.gitignore b/.gitignore index 04eea848..9e078da1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,10 @@ lib/ # Rust build artifacts /target **/target +**/Cargo.lock + +# Personal notes +rust_session/student_registry_v2/notes/ # Hardhat / Foundry build artifacts artifacts/ diff --git a/rust_session/Cargo.lock b/rust_session/Cargo.lock deleted file mode 100644 index bf268c9a..00000000 --- a/rust_session/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "rust_session" -version = "0.1.0" diff --git a/rust_session/src/grade.rs b/rust_session/src/grade.rs new file mode 100644 index 00000000..fbbfd838 --- /dev/null +++ b/rust_session/src/grade.rs @@ -0,0 +1,31 @@ +#[derive(Debug)] +pub enum Grade { + First, + Second, + Third +} + +impl Grade { + pub fn get_grade_points(&self) -> &str { + match self { + Grade::First => "Cohort 1", + Grade::Second => "Cohort 2", + Grade::Third => "Cohort 3", + } + } +} + +#[derive(Debug)] +pub enum Sex { + Male, + Female +} + +impl Sex { + pub fn get_sex(&self) { + match self { + Sex::Male => println!("Male"), + Sex::Female => println!("Female"), + } + } +} \ No newline at end of file diff --git a/rust_session/src/main.rs b/rust_session/src/main.rs index c11cc20e..9dd41a56 100644 --- a/rust_session/src/main.rs +++ b/rust_session/src/main.rs @@ -1,17 +1,38 @@ -mod sub; -mod sum; -mod ownership; -mod array; -mod mut_ex; - +// mod sub; +// mod sum; +// mod ownership; +// mod array; +// mod mut_ex; +// mod grade; +// mod voters; +// mod student_struct; fn main() { // use sub::sub; + // use crate::voters::{Age, EligibleVoters}; // sub(10, 5); // ownership::test_ownership(); // ownership::call_name(); // array::test_array(); // ownership::test_move(); // ownership::call_greet(); - mut_ex::test_mut(); + // mut_ex::test_mut(); + // grade::Grade::First.get_grade_points(); + // grade::Grade::Second.get_grade_points(); + // grade::Grade::Third.get_grade_points(); + // grade::Sex::Male.get_sex(); + // grade::Sex::Female.get_sex(); + // voters::Age::SilverJubilee.get_age(); + // voters::Age::GoldenJubilee.get_age(); + // voters::Age::PlatinumJubilee.get_age(); + // voters::Age::Centenarian.get_age(); + // voters::EligibleVoters::Juvenile.get_eligible_voters(); + // voters::EligibleVoters::Teenager.get_eligible_voters(); + // voters::EligibleVoters::Adult.get_eligible_voters(); + + // let age = Age::SilverJubilee; + // let eligible_voters = EligibleVoters::Teenager; + // println!("Age: {}", age.get_age()); + // println!("Eligible Voters: {}", eligible_voters.get_eligible_voters()); + } diff --git a/rust_session/src/student_struct.rs b/rust_session/src/student_struct.rs new file mode 100644 index 00000000..67ee21cd --- /dev/null +++ b/rust_session/src/student_struct.rs @@ -0,0 +1,37 @@ +#[derive(Debug)] +pub enum Status{ + Pending, + Completed, + InProgress, + Cancelled, +} + +impl Status { + pub fn get_status(&self) -> &str { + match self { + Status::Pending => "Pending", + Status::Completed => "Completed", + Status::InProgress => "InProgress", + Status::Cancelled => "Cancelled", + } + } +} + + +pub struct Todo { + pub id: u8, + pub title: String, + pub description: String, + pub status: Status, +} + +impl Todo { + pub fn new(id: u8, title: String, description: String, status: Status) -> Todo { + Todo { + id, + title, + description, + status + } + } +} \ No newline at end of file diff --git a/rust_session/src/voters.rs b/rust_session/src/voters.rs new file mode 100644 index 00000000..2d6a3918 --- /dev/null +++ b/rust_session/src/voters.rs @@ -0,0 +1,35 @@ +#[derive(Debug)] +pub enum Age { + SilverJubilee, + GoldenJubilee, + PlatinumJubilee, + Centenarian +} + +impl Age { + pub fn get_age(&self) -> &str { + match self { + Age::SilverJubilee => "25 years", + Age::GoldenJubilee => "50 years", + Age::PlatinumJubilee => "75 years", + Age::Centenarian => "100 years", + } + } +} + +#[derive(Debug)] +pub enum EligibleVoters { + Juvenile, + Teenager, + Adult +} + +impl EligibleVoters { + pub fn get_eligible_voters(&self) -> &str { + match self { + EligibleVoters::Juvenile => "17 years and below", + EligibleVoters::Teenager => "18 years and above", + EligibleVoters::Adult => "35 years and above", + } + } +} \ No newline at end of file diff --git a/rust_session/student_registry/Cargo.lock b/rust_session/student_registry/Cargo.lock deleted file mode 100644 index e7f8ee38..00000000 --- a/rust_session/student_registry/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "student_registry" -version = "0.1.0" diff --git a/rust_session/student_registry/src/main.rs b/rust_session/student_registry/src/main.rs index 7ae18ff7..c4076c08 100644 --- a/rust_session/student_registry/src/main.rs +++ b/rust_session/student_registry/src/main.rs @@ -1,11 +1,11 @@ mod grade; mod registry; mod student_struct; -mod utils; +// mod utils; use grade::{Grade, Sex}; use registry::Registry; -use student_struct::Student; +// use student_struct::Student; fn main() { // let g = Grade::Second; @@ -15,29 +15,44 @@ fn main() { // let ss = Student::new(); // println!("stund") - // let mut reg = Registry::new(); + let mut reg = Registry::new(); + + reg.add("Victor", 20, Sex::Male, Grade::First, 78.5,); + reg.add("Kosi", 22, Sex::Female, Grade::Second, 64.0); + reg.add("Yusrah", 21, Sex::Female, Grade::First, 91.0); - // reg.add("Victor", 20, Grade::First, 78.5); - // reg.add("Kosi", 22, Grade::Second, 64.0); - // reg.add("Yusrah", 21, Grade::First, 91.0); + reg.list_all(); - // reg.list_all();] - let sex = Sex::Male; - println!("sex: {:?}", sex.to_str()); + let second_id = reg.students[1].id.clone(); - // let s: Student = Student::new(1, String::from("Testimony"), 16, Sex::Female, Grade::Third, 40.5); - let s: Student = Student::new( - 1, - "Testimony".to_string(), - 16, - Sex::Female, - Grade::Third, - 40.5, - ); - println!("student here: {:#?}", s); + match reg.find_by_id(second_id) { + Some(student) => println!("Found student: {} with ID: {}", student.name, student.id), + None => println!("Student not found"), + } - println!("student id: {}", s.id); - println!("student name: {}", s.name); - println!("student age: {}", s.age); + reg.update(second_id, "joy", 25, 50.0); + println!(); + reg.list_all(); + + + + + // let sex = Sex::Male; + // println!("sex: {:?}", sex.to_str()); + + // // let s: Student = Student::new(1, String::from("Testimony"), 16, Sex::Female, Grade::Third, 40.5); + // let s: Student = Student::new( + // 1, + // "Testimony".to_string(), + // 16, + // Sex::Female, + // Grade::Third, + // 40.5, + // ); + // println!("student here: {:#?}", s); + + // println!("student id: {}", s.id); + // println!("student name: {}", s.name); + // println!("student age: {}", s.age); } diff --git a/rust_session/student_registry/src/registry.rs b/rust_session/student_registry/src/registry.rs index 146dc186..83a9ae1f 100644 --- a/rust_session/student_registry/src/registry.rs +++ b/rust_session/student_registry/src/registry.rs @@ -7,6 +7,13 @@ pub struct Registry { } impl Registry { + pub fn new() -> Registry { + Registry { + students: Vec::new(), + next_id: 0, + } + } + pub fn add(&mut self, name: &str, age: u8, sex: Sex, grade: Grade, score: f32) { let id = self.next_id; let student = Student::new(id, name.to_string(), age, sex, grade, score); @@ -36,4 +43,28 @@ impl Registry { ); } } + + pub fn find_by_id(&self, id: u32) -> Option<&Student> { + self.students.iter().find(|s| s.id == id) + } + // - .iter() loops through the vec without taking ownership + // - .find() returns the first match wrapped in Option<&Student> + // - Option means it can be Some(student) if found, or None if not — Rust forces you to handle both cases, no null panics + + pub fn delete(&mut self, id: u32) { + self.students.retain(|s| s.id != id); + } + // - .retain() keeps only elements where the condition is true + // - So s.id != id means "keep everyone whose id is NOT the one we want to remove" + // - It mutates the vec in place — no need to find an index + + pub fn update(&mut self, id: u32, name: &str, age: u8, score: f32) { + if let Some(student) = self.students.iter_mut().find(|s| s.id == id) { + student.name = name.to_string(); + student.age = age; + student.score = score; + } + } + // - .iter_mut() gives mutable references so you can modify fields in place + // - if let Some(student) is Rust's clean way to say "if found, do this, otherwise skip" } diff --git a/rust_session/student_registry_v2/Cargo.toml b/rust_session/student_registry_v2/Cargo.toml new file mode 100644 index 00000000..1bf734cd --- /dev/null +++ b/rust_session/student_registry_v2/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "student_registry_v2" +version = "0.1.0" +edition = "2021" + +[dependencies] +uuid = { version = "1", features = ["v4"] } diff --git a/rust_session/student_registry_v2/src/grade.rs b/rust_session/student_registry_v2/src/grade.rs new file mode 100644 index 00000000..401b0c3a --- /dev/null +++ b/rust_session/student_registry_v2/src/grade.rs @@ -0,0 +1,31 @@ +#[derive(Debug, PartialEq)] +pub enum Grade { + First, + Second, + Third, +} + +impl Grade { + pub fn as_str(&self) -> &str { + match self { + Grade::First => "Cohort 1", + Grade::Second => "Cohort 2", + Grade::Third => "Cohort 3", + } + } +} + +#[derive(Debug)] +pub enum Sex { + Male, + Female, +} + +impl Sex { + pub fn to_str(&self) -> &str { + match self { + Sex::Male => "male", + Sex::Female => "female", + } + } +} diff --git a/rust_session/student_registry_v2/src/main.rs b/rust_session/student_registry_v2/src/main.rs new file mode 100644 index 00000000..be68411d --- /dev/null +++ b/rust_session/student_registry_v2/src/main.rs @@ -0,0 +1,49 @@ +mod grade; +mod registry; +mod student_struct; + +use grade::{Grade, Sex}; +use registry::Registry; + +fn section(title: &str) { + let width = 60; + println!("\n{}", "=".repeat(width)); + println!("{:^width$}", title, width = width); + println!("{}", "=".repeat(width)); +} + +fn main() { + let mut reg = Registry::new(); + + section("REGISTERING STUDENTS"); + reg.add("Victor", 20, Sex::Male, Grade::First, 78.5); + reg.add("Kosi", 22, Sex::Female, Grade::Second, 64.0); + reg.add("Yusrah", 21, Sex::Female, Grade::First, 91.0); + + section("ALL STUDENTS"); + reg.list_all(); + + let first_id = reg.students[0].id.clone(); + + // section("FIND BY ID"); + // match reg.find_by_id(&first_id) { + // Some(s) => { + // println!(" Name : {}", s.name); + // println!(" ID : {}", s.id); + // println!(" Age : {}", s.age); + // println!(" Sex : {}", s.sex.to_str()); + // println!(" Grade : {}", s.grade.as_str()); + // println!(" Score : {:.1}", s.score); + // } + // None => println!(" Not found"), + // } + + // section("UPDATE STUDENT"); + // reg.update(&first_id, "Victor Updated", 21, 85.0); + // println!(); + // reg.list_all(); + + section("DELETE STUDENT"); + reg.delete(&first_id); + reg.list_all(); +} diff --git a/rust_session/student_registry_v2/src/registry.rs b/rust_session/student_registry_v2/src/registry.rs new file mode 100644 index 00000000..17b33dde --- /dev/null +++ b/rust_session/student_registry_v2/src/registry.rs @@ -0,0 +1,76 @@ +use uuid::Uuid; + +use crate::grade::{Grade, Sex}; +use crate::student_struct::Student; + +pub struct Registry { + pub students: Vec, +} + +impl Registry { + pub fn new() -> Registry { + Registry { + students: Vec::new(), + } + } + + pub fn add(&mut self, name: &str, age: u8, sex: Sex, grade: Grade, score: f32) { + let id = Uuid::new_v4().to_string(); + let student = Student::new(id, name.to_string(), age, sex, grade, score); + println!(" [+] Registered: {:<16} (ID: {})", student.name, student.id); + self.students.push(student); + } + + pub fn list_all(&self) { + if self.students.is_empty() { + println!(" (no students enrolled yet)"); + return; + } + println!( + " {:<36} {:<16} {:<4} {:<8} {:<9} {}", + "ID", "Name", "Age", "Sex", "Grade", "Score" + ); + println!(" {}", "-".repeat(87)); + for student in &self.students { + println!( + " {:<36} {:<16} {:<4} {:<8} {:<9} {:.1}", + student.id, + student.name, + student.age, + student.sex.to_str(), + student.grade.as_str(), + student.score, + ); + } + } + + // Returns a shared reference to the student if found, or None + pub fn find_by_id(&self, id: &str) -> Option<&Student> { + self.students.iter().find(|s| s.id == id) + // ------ in javascript ------- + // this.students.find(s => s.id === id) + } + + // Updates name, age, and score for the student with the given id + pub fn update(&mut self, id: &str, name: &str, age: u8, score: f32) { + if let Some(student) = self.students.iter_mut().find(|s| s.id == id) { + student.name = name.to_string(); + student.age = age; + student.score = score; + println!(" [~] Updated: {} (ID: {})", student.name, id); + } else { + println!(" [!] Student with ID {} not found", id); + } + } + + // Removes the student with the given id from the registry + pub fn delete(&mut self, id: &str) { + let before = self.students.len(); + self.students.retain(|s| s.id != id); + if self.students.len() < before { + println!(" [-] Deleted student with ID: {}", id); + } else { + println!(" [!] Student with ID {} not found", id); + } + } +} diff --git a/rust_session/student_registry_v2/src/student_struct.rs b/rust_session/student_registry_v2/src/student_struct.rs new file mode 100644 index 00000000..3eaa29e0 --- /dev/null +++ b/rust_session/student_registry_v2/src/student_struct.rs @@ -0,0 +1,24 @@ +use crate::grade::{Grade, Sex}; + +#[derive(Debug)] +pub struct Student { + pub id: String, // UUID string instead of u32 + pub name: String, + pub age: u8, + pub sex: Sex, + pub grade: Grade, + pub score: f32, +} + +impl Student { + pub fn new(id: String, name: String, age: u8, sex: Sex, grade: Grade, score: f32) -> Student { + Student { + id, + name, + age, + sex, + grade, + score, + } + } +}