|
| 1 | +use std::io; |
| 2 | + |
| 3 | +// STRUCTS --> defined outside main() |
| 4 | + |
| 5 | +struct User { |
| 6 | + username: String, |
| 7 | + email: String, |
| 8 | + age: u32, |
| 9 | + is_active: bool, |
| 10 | +} |
| 11 | + |
| 12 | +struct Rectangle { |
| 13 | + width: f64, |
| 14 | + length: f64, |
| 15 | +} |
| 16 | + |
| 17 | +// impl = attach methods to a struct |
| 18 | +impl Rectangle { |
| 19 | + fn new(width: f64, length: f64) -> Self { |
| 20 | + Self { width, length } |
| 21 | + } |
| 22 | + |
| 23 | + // & self = borrow the struct -> don't consume it |
| 24 | + |
| 25 | + fn area(&self) -> f64 { |
| 26 | + self.width * self.length |
| 27 | + } |
| 28 | + |
| 29 | + fn perimeter(&self) -> f64 { |
| 30 | + 2.0 * (self.width + self.length) |
| 31 | + } |
| 32 | + |
| 33 | + fn is_square(&self) -> bool { |
| 34 | + self.width == self.length |
| 35 | + } |
| 36 | +} |
| 37 | + |
| 38 | +// ENUMS --> defined outside main() |
| 39 | +enum Direction { |
| 40 | + North, |
| 41 | + South, |
| 42 | + West, |
| 43 | + East, |
| 44 | +} |
| 45 | + |
| 46 | +// Enum with DATA attached to variants |
| 47 | +enum Shape { |
| 48 | + Circle(f64), |
| 49 | + Rectangle(f64, f64), |
| 50 | + Triangle(f64, f64, f64), |
| 51 | +} |
| 52 | + |
| 53 | +enum Cmd { |
| 54 | + Echo(String), |
| 55 | + Cd(String), |
| 56 | + Exit, |
| 57 | + Unknown(String), |
| 58 | +} |
| 59 | + |
| 60 | +// FUNCTIONS --> defined outside main() |
| 61 | + |
| 62 | +fn area_of_shape(what_shape: Shape) -> f64 { |
| 63 | + match what_shape { |
| 64 | + Shape::Circle(r) => 3.14 * r * r, |
| 65 | + Shape::Rectangle(w, h) => w * h, |
| 66 | + Shape::Triangle(a, b, c) => { |
| 67 | + let s = (a + b + c) / 2.0; |
| 68 | + (s * (s - a) * (s - b) * (s - c)).sqrt() |
| 69 | + } |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +fn parse_command(input: &str) -> Cmd { |
| 74 | + let parts: Vec<&str> = input.splitn(2, ' ').collect(); |
| 75 | + match parts[0] { |
| 76 | + "echo" => Cmd::Echo(parts.get(1).unwrap_or(&"").to_string()), // unwrap_or(&"") means if value exists -> use it, if not -> use empty string |
| 77 | + "cd" => Cmd::Cd(parts.get(1).unwrap_or(&"").to_string()), |
| 78 | + "exit" => Cmd::Exit, |
| 79 | + other => Cmd::Unknown(other.to_string()), |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +fn main() { |
| 84 | + // PART 1 : Creating and Using Structs |
| 85 | + |
| 86 | + let user = User { |
| 87 | + // Direct struct initialization |
| 88 | + username: String::from("alice"), |
| 89 | + email: String::from("abc@gmail.com"), |
| 90 | + age: 20, |
| 91 | + is_active: true, |
| 92 | + }; |
| 93 | + |
| 94 | + println!("username: {}", user.username); |
| 95 | + println!("email: {}", user.email); |
| 96 | + println!("age: {}", user.age); |
| 97 | + println!("active: {}", user.is_active); |
| 98 | + |
| 99 | + // PART 2; Structs with Methods |
| 100 | + |
| 101 | + let rect = Rectangle::new(10.0, 5.0); // constructor like |
| 102 | + println!("area: {}", rect.area()); |
| 103 | + println!("perimeter {}", rect.perimeter()); |
| 104 | + println!("is square: {}", rect.is_square()); |
| 105 | + |
| 106 | + let square = Rectangle::new(4.0, 4.0); |
| 107 | + println!("is square: {}", square.is_square()); |
| 108 | + |
| 109 | + // Part 3: Basic Enume with Match |
| 110 | + |
| 111 | + let dir = Direction::North; |
| 112 | + match dir { |
| 113 | + Direction::North => println!("Going north!"), |
| 114 | + Direction::South => println!("Going south!"), |
| 115 | + Direction::East => println!("Going east!"), |
| 116 | + Direction::West => println!("Going west!"), |
| 117 | + } |
| 118 | + |
| 119 | + // PART 4 : Enum with Date |
| 120 | + |
| 121 | + let c = Shape::Circle(5.0); |
| 122 | + let r = Shape::Rectangle(4.0, 6.0); |
| 123 | + let t = Shape::Triangle(3.0, 4.0, 5.0); |
| 124 | + |
| 125 | + println!("Circle area: {:.2}", area_of_shape(c)); |
| 126 | + println!("Rectangle area: {:.2}", area_of_shape(r)); |
| 127 | + println!("Triangle area: {:.2}", area_of_shape(t)); |
| 128 | + |
| 129 | + // PART 6: Option => values that might not exist |
| 130 | + |
| 131 | + let numbers = vec![1, 2, 3, 4, 5]; |
| 132 | + |
| 133 | + // .get() return Option -- safely gets in index |
| 134 | + match numbers.get(2) { |
| 135 | + Some(n) => println!("Found {}", n), |
| 136 | + None => println!("Not found"), |
| 137 | + } |
| 138 | + |
| 139 | + // PART 6: Result - operations that might fail |
| 140 | + |
| 141 | + let good = "42".parse::<i32>(); // parsing a valid number |
| 142 | + let bad = "abc".parse::<i32>(); // parsing invalid text |
| 143 | + |
| 144 | + match good { |
| 145 | + Ok(n) => println!("Parsed: {}", n), |
| 146 | + Err(e) => println!("Error: {}", e), |
| 147 | + } |
| 148 | + |
| 149 | + match bad { |
| 150 | + Ok(n) => println!("Parsed: {}", n), |
| 151 | + Err(e) => println!("could not parse: {}", e), |
| 152 | + } |
| 153 | + |
| 154 | + // PART 7: Mini Shell using Enum |
| 155 | + |
| 156 | + loop { |
| 157 | + let mut input = String::new(); |
| 158 | + io::stdin().read_line(&mut input).unwrap(); |
| 159 | + let input = input.trim(); |
| 160 | + |
| 161 | + match parse_command(input) { |
| 162 | + Cmd::Echo(text) => print!("{}\n", text), |
| 163 | + Cmd::Cd(path) => println!("Would change to : {}", path), |
| 164 | + Cmd::Exit => { |
| 165 | + println!("See yaa!!"); |
| 166 | + break; |
| 167 | + } |
| 168 | + Cmd::Unknown(c) => println!("Unknown: {}", c), |
| 169 | + } |
| 170 | + } |
| 171 | +} |
0 commit comments