use std::time::{SystemTime, UNIX_EPOCH};
#[allow(dead_code)]
enum Temperature<T> {
Celsius(T),
Fahrenheit(f32),
}
use std::arch::asm;
use Temperature::Celsius;
use Temperature::Fahrenheit;
struct Point {
x: i32,
y: i32,
}
fn generate_random_number() -> i32 {
let since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let seed = since_epoch.as_secs();
(seed % 101) as i32
}
fn main() {
//destructing
//enum
//guards
let temperature = Temperature::Celsius(35);
match temperature {
Temperature::Celsius(t) if t > 30 => {
println!("{}C is above 30 Celsius", t)
},
// The `if condition` part ^ is a guard
Temperature::Celsius(t) => {
println!("{}C is equal to or below 30 Celsius", t)
},
Temperature::Fahrenheit(t) if t > 86.0 => {
println!("{}F is above 86 Fahrenheit", t)
},
Temperature::Fahrenheit(t) => {
println!("{}F is equal to or below 86 Fahrenheit", t)
}
}
// unsafe {
// asm!("int 3");
// }
//struct
let point = Point { x: 10, y: 20 };
match point {
Point { x, y } => println!("Point at ({}, {})", x, y),
}
//tuple
let tuple = (1, 2, 3);
match tuple {
(x, y, z) => println!("Tuple values: {}, {}, {}", x, y, z),
}
//array
let array = [1, 2, 3];
match array {
[first, second, ..] => println!("First: {}, Second: {}", first, second),
_ => println!("Not a match"),
}
let number = 4;
match number {
n if n % 2 == 0 => println!("Even number: {}", n),
n => println!("Odd number: {}", n),
}
//pointer/reference
// Assign a reference of type `i32`. The `&` signifies there
// is a reference being assigned.
let reference = &4;
match reference {
// If `reference` is pattern matched against `&val`, it results
// in a comparison like:
// `&i32`
// `&val`
// ^ We see that if the matching `&`s are dropped, then the `i32`
// should be assigned to `val`.
&val => println!("Got a value via destructuring: {:?}", val),
}
// To avoid the `&`, you dereference before matching.
match *reference {
val => println!("Got a value via dereferencing: {:?}", val),
}
// Accordingly, by defining 2 values without references, references
// can be retrieved via `ref` and `ref mut`.
let value = 5;
let mut mut_value = 6;
// Use `ref` keyword to create a reference.
match value {
ref r => println!("Got a reference to a value: {:?}", r),
}
// Use `ref mut` similarly.
match mut_value {
ref mut m => {
// Got a reference. Gotta dereference it before we can
// add anything to it.
*m += 10;
println!("We added 10. `mut_value`: {:?}", m);
},
}
//if let
let option_value: Option<i32> = Some(5);
if let Some(v) = option_value {
println!("Got a value: {}", v);
}
//whie let
while let Some(v) = option_value {
println!("Still got a value: {}", v);
break;
}
//let-else
let t = (Temperature::Celsius(35), Temperature::<f32>::Fahrenheit(35.0));
let (Celsius(t0), Fahrenheit(t1)) = t else {
panic!("Destructing failed!\n");
};
print!("t0 = {}, t1 = {}\n", t0, t1);
//binding
println!("Tell me what type of person you are");
let age = generate_random_number();
match age {
0 => println!("I haven't celebrated my first birthday yet"),
// Could `match` 1 ..= 12 directly but then what age
// would the child be? Instead, bind to `n` for the
// sequence of 1 ..= 12. Now the age can be reported.
n @ 1 ..= 12 => println!("I'm a child of age {:?}", n),
n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n),
// Nothing bound. Return the result.
n => println!("I'm an old person of age {:?}", n),
}
unsafe {
asm!("int 3");
}
}