commit 59127d6cd476916f131cfcfcf7de2dab791c9088
parent 04112f46ff71e5df6aea7a26189757f000d4c70c
Author: Vetle Haflan <vetle@haflan.dev>
Date: Thu, 28 Oct 2021 13:24:30 +0200
Add experiments based on rust-by-example
Diffstat:
5 files changed, 352 insertions(+), 0 deletions(-)
diff --git a/rust/custom_types.rs b/rust/custom_types.rs
@@ -0,0 +1,65 @@
+// Custom types
+// struct : structure
+// enum : enumeration
+
+// Structs
+// Tuple structs : Essentially named tuples, i.e. fields
+struct Tuple(i32, i32, i32, i32);
+// Classic structs : Named fields, like C
+#[derive(Debug)]
+struct Classic {
+ a_field: i32,
+ b_field: String,
+}
+// Unit structs : Field-less, useful for generics
+struct Unit;
+
+enum Status {
+ InSync,
+ Syncing,
+ Error,
+}
+
+enum StatusExplicit {
+ InSync = 1,
+ Syncing = 2,
+ Error = 3,
+}
+
+impl Status {
+ // Instance function
+ fn print(&self, prefix: String) {
+ let mut str_status = match self {
+ Self::InSync => String::from("all good"),
+ Self::Syncing => String::from("working!"),
+ Self::Error => String::from("oh no"),
+ };
+ println!("{} {}", prefix, str_status);
+ }
+ // Like Java static function
+ fn get_error() -> Status {
+ return Status::Error;
+ }
+}
+
+const STATUS_PREFIX: &str = "It's";
+
+fn main() {
+ let c = Classic {
+ a_field: 234,
+ b_field: String::from("Some string"),
+ };
+ println!("{:?}", c);
+ let t = Tuple(1, 3, 5, 7);
+ println!("{:?}", t.1);
+ let s = Status::Syncing;
+ // Call .print on the instance
+ s.print(String::from(STATUS_PREFIX));
+ // `use`, like used here, makes the `Status::` prefix unnecessary.
+ // Notice the wildcard to include all instead of individual fields
+ use crate::Status::*;
+ InSync.print(String::from("Now it's"));
+ println!("Implicit discriminator: {}", InSync as i32);
+ println!("Explicit: {}", StatusExplicit::InSync as i32);
+ println!("Static function: {}", Status::get_error() as i32)
+}
diff --git a/rust/custom_types2.rs b/rust/custom_types2.rs
@@ -0,0 +1,106 @@
+#[derive(Debug)]
+struct Person {
+ name: String,
+ age: u8,
+}
+
+// A unit struct
+struct Unit;
+
+// A tuple struct
+struct Pair(i32, f32);
+
+// A struct with two fields
+#[derive(Debug)]
+struct Point {
+ x: f32,
+ y: f32,
+}
+
+// Structs can be reused as fields of another struct
+#[derive(Debug)]
+#[allow(dead_code)]
+struct Rectangle {
+ // A rectangle can be specified by where the top left and bottom right
+ // corners are in space.
+ top_left: Point,
+ bottom_right: Point,
+}
+
+fn rect_area(r: &Rectangle) -> f32 {
+ // Nested struct destructuring demonstrated here:
+ let Rectangle {
+ top_left: Point {
+ x: ref x1,
+ y: ref y1,
+ },
+ bottom_right: Point {
+ x: ref x2,
+ y: ref y2,
+ },
+ } = *r;
+ (x1 - x2) * (y1 - y2)
+}
+
+fn square(p: Point, v: f32) -> Rectangle {
+ Rectangle {
+ top_left: Point { x: p.x, y: p.y + v },
+ bottom_right: Point { x: p.x + v, y: p.y },
+ }
+}
+
+fn main() {
+ // Create struct with field init shorthand
+ let name = String::from("Peter");
+ let age = 27;
+ let peter = Person { name, age };
+
+ // Print debug struct
+ println!("{:?}", peter);
+
+ // Instantiate a `Point`
+ let point: Point = Point { x: 10.3, y: 0.4 };
+
+ // Access the fields of the point
+ println!("point coordinates: ({}, {})", point.x, point.y);
+
+ // Make a new point by using struct update syntax to use the fields of our
+ // other one
+ let bottom_right = Point { x: 5.2, ..point };
+
+ // `bottom_right.y` will be the same as `point.y` because we used that field
+ // from `point`
+ println!("second point: ({}, {})", bottom_right.x, bottom_right.y);
+
+ // Destructure the point using a `let` binding
+ let Point {
+ x: left_edge,
+ y: top_edge,
+ } = point;
+
+ let _rectangle = Rectangle {
+ // struct instantiation is an expression too
+ top_left: Point {
+ x: left_edge,
+ y: top_edge,
+ },
+ bottom_right: bottom_right,
+ };
+
+ // Instantiate a unit struct
+ let _unit = Unit;
+
+ // Instantiate a tuple struct
+ let pair = Pair(1, 0.1);
+
+ // Access the fields of a tuple struct
+ println!("pair contains {:?} and {:?}", pair.0, pair.1);
+
+ // Destructure a tuple struct
+ let Pair(integer, decimal) = pair;
+
+ println!("pair contains {:?} and {:?}", integer, decimal);
+ println!("rect: {:?}", _rectangle);
+ println!("area: {}", rect_area(&_rectangle));
+ println!("rect: {:?}", square(Point { x: 0.0, y: 0.0 }, 3.5))
+}
diff --git a/rust/hello_world.rs b/rust/hello_world.rs
@@ -0,0 +1,140 @@
+fn main() {
+ /*
+ * Formatted print
+ */
+ println!("My name is {0}, {1} {0}", "Bond", "James");
+ let pi = 3.141592;
+ // Implicit position
+ println!("Pi is roughly {:.2}", pi);
+ // Explicit position
+ println!("Pi is roughly {0:.2}", pi);
+ // Named
+ println!("Pi is roughly {num:.2}", num = pi);
+
+ /*
+ * Debug
+ */
+ println!("DEBUG");
+
+ // v derive(DEBUG) trait lets you use {:?} in println!, but {} though
+ #[derive(Debug)]
+ struct Person<'a> {
+ name: &'a str,
+ age: u8,
+ }
+ let name = "Peter";
+ let age = 27;
+ let peter = Person { name, age };
+
+ // Pretty print
+ println!("{:?}", peter);
+
+ /*
+ * Display
+ */
+ use std::fmt;
+ // Define a structure where the fields are nameable for comparison.
+ #[derive(Debug)]
+ struct Complex {
+ real: f64,
+ imag: f64,
+ }
+
+ // Implement `Display`, which defines how `{}` prints the struct in `println!`
+ // v derive(DEBUG) trait lets you use {:?} in println!, but {} though
+ impl fmt::Display for Complex {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // Customize so only `x` and `y` are denoted.
+ write!(f, "{} + {}i", self.real, self.imag)
+ }
+ }
+
+ println!("DISPLAY");
+ println!(
+ "Display: {}",
+ Complex {
+ real: 3.3,
+ imag: 7.2
+ }
+ );
+
+ println!(
+ "Debug: {:?}",
+ Complex {
+ real: 3.3,
+ imag: 7.2
+ }
+ );
+
+ println!("TESTCASE: LIST");
+ // Define a structure named `List` containing a `Vec`.
+ struct List(Vec<i32>);
+
+ impl fmt::Display for List {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // Extract the value using tuple indexing,
+ // and create a reference to `vec`.
+ let vec = &self.0;
+
+ write!(f, "[")?;
+
+ // Iterate over `v` in `vec` while enumerating the iteration
+ // count in `count`.
+ for (count, v) in vec.iter().enumerate() {
+ // For every element except the first, add a comma.
+ // Use the ? operator to return on errors.
+ if count != 0 {
+ write!(f, ", ")?;
+ }
+ write!(f, "{}: {}", count, v)?;
+ }
+
+ // Close the opened bracket and return a fmt::Result value.
+ write!(f, "]")
+ }
+ }
+ let v = List(vec![1, 2, 3]);
+ println!("{}", v);
+
+ println!("FORMATTING");
+
+ #[derive(Debug)]
+ struct Color {
+ red: u8,
+ green: u8,
+ blue: u8,
+ }
+
+ impl fmt::Display for Color {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "RGB ({0}, {1}, {2}) 0x{0:02X}{1:02X}{2:02X}",
+ self.red, self.green, self.blue
+ )
+ }
+ }
+ for color in [
+ Color {
+ red: 128,
+ green: 255,
+ blue: 90,
+ },
+ Color {
+ red: 0,
+ green: 3,
+ blue: 254,
+ },
+ Color {
+ red: 0,
+ green: 0,
+ blue: 0,
+ },
+ ]
+ .iter()
+ {
+ // Switch this to use {} once you've added an implementation
+ // for fmt::Display.
+ println!("{}", *color);
+ }
+}
diff --git a/rust/primitives.rs b/rust/primitives.rs
@@ -0,0 +1,38 @@
+use std::fmt;
+
+struct Matrix(f32, f32, f32, f32);
+
+fn transpose(m: Matrix) -> Matrix {
+ // `let` can be used to bind the members of a tuple to variables
+ Matrix(m.0, m.2, m.1, m.3)
+}
+
+impl fmt::Display for Matrix {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "( {} {} )\n( {} {} )", self.0, self.1, self.2, self.3)
+ }
+}
+
+fn main() {
+ let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
+ println!("Matrix:\n{}", matrix);
+ println!("Transpose::\n{}", transpose(matrix));
+
+ //i = 5;
+ println!("ARRAYS AND SLICES");
+ // Arrays: Fixed length, known at compile time
+ let arr_five_nums: [i32; 5] = [1, 5, 3, 4, 2];
+ let arr_ten_zeros: [i32; 10] = [0; 10];
+ println!("{:?}", arr_five_nums);
+ println!("{:?}", arr_ten_zeros);
+ // These line will break the build or, if `let i = 5` is moved up,
+ // lead to panic
+ //// let i = 5;
+ //// println!("{}", arr_five_nums[i]);
+ //
+ // Slices: Similar to arrays, but length unknown at compile time.
+ // Essentially consists of (pointer to first element, length)
+ // Arrays can be automatically borrowed as slices
+ let slice: &[i32] = &arr_five_nums[1..4];
+ println!("{:?}", slice);
+}
diff --git a/rust/types.rs b/rust/types.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("yes");
+}