From 3a4936d455e300286bdb4d5b1cfbb7e78e1c156e Mon Sep 17 00:00:00 2001 From: ahgamut <41098605+ahgamut@users.noreply.github.com> Date: Sun, 26 Jun 2022 19:11:30 +0530 Subject: [PATCH] add examples from Rust By Example examples built into 3 separate binaries --- src/bin/example1.rs | 146 +++++++++++++++++++++++++ src/bin/example2.rs | 160 ++++++++++++++++++++++++++++ src/{main.rs => bin/hello_world.rs} | 0 3 files changed, 306 insertions(+) create mode 100644 src/bin/example1.rs create mode 100644 src/bin/example2.rs rename src/{main.rs => bin/hello_world.rs} (100%) diff --git a/src/bin/example1.rs b/src/bin/example1.rs new file mode 100644 index 0000000..719e3da --- /dev/null +++ b/src/bin/example1.rs @@ -0,0 +1,146 @@ +#![allow(dead_code)] +use std::mem; +// https://doc.rust-lang.org/rust-by-example/primitives.html +fn example1 () { + // Variables can be type annotated. + let logical: bool = true; + + let a_float: f64 = 1.0; // Regular annotation + let an_integer = 5i32; // Suffix annotation + + // Or a default will be used. + let default_float = 3.0; // `f64` + let default_integer = 7; // `i32` + + // A type can also be inferred from context + let mut inferred_type = 12; // Type i64 is inferred from another line + inferred_type = 4294967296i64; + + // A mutable variable's value can be changed. + let mut mutable = 12; // Mutable `i32` + mutable = 21; +} + +// https://doc.rust-lang.org/rust-by-example/primitives/literals.html +fn example1b() { + // Integer addition + println!("1 + 2 = {}", 1u32 + 2); + + // Integer subtraction + println!("1 - 2 = {}", 1i32 - 2); + // TODO ^ Try changing `1i32` to `1u32` to see why the type is important + + // Short-circuiting boolean logic + println!("true AND false is {}", true && false); + println!("true OR false is {}", true || false); + println!("NOT true is {}", !true); + + // Bitwise operations + println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101); + println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101); + println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101); + println!("1 << 5 is {}", 1u32 << 5); + println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2); + + // Use underscores to improve readability! + println!("One million is written as {}", 1_000_000u32); +} + +// https://doc.rust-lang.org/rust-by-example/primitives/tuples.html +// Tuples can be used as function arguments and as return values +fn reverse(pair: (i32, bool)) -> (bool, i32) { + // `let` can be used to bind the members of a tuple to variables + let (integer, boolean) = pair; + + (boolean, integer) +} + +// The following struct is for the activity. +#[derive(Debug)] +struct Matrix(f32, f32, f32, f32); + +fn example1c() { + // A tuple with a bunch of different types + let long_tuple = (1u8, 2u16, 3u32, 4u64, + -1i8, -2i16, -3i32, -4i64, + 0.1f32, 0.2f64, + 'a', true); + + // Values can be extracted from the tuple using tuple indexing + println!("long tuple first value: {}", long_tuple.0); + println!("long tuple second value: {}", long_tuple.1); + + // Tuples can be tuple members + let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16); + + // Tuples are printable + println!("tuple of tuples: {:?}", tuple_of_tuples); + + // But long Tuples cannot be printed + // let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); + // println!("too long tuple: {:?}", too_long_tuple); + // TODO ^ Uncomment the above 2 lines to see the compiler error + + let pair = (1, true); + println!("pair is {:?}", pair); + + println!("the reversed pair is {:?}", reverse(pair)); + + // To create one element tuples, the comma is required to tell them apart + // from a literal surrounded by parentheses + println!("one element tuple: {:?}", (5u32,)); + println!("just an integer: {:?}", (5u32)); + + //tuples can be destructured to create bindings + let tuple = (1, "hello", 4.5, true); + + let (a, b, c, d) = tuple; + println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d); + + let matrix = Matrix(1.1, 1.2, 2.1, 2.2); + println!("{:?}", matrix); +} + + +// This function borrows a slice +fn analyze_slice(slice: &[i32]) { + println!("first element of the slice: {}", slice[0]); + println!("the slice has {} elements", slice.len()); +} + +fn example1d() { + // Fixed-size array (type signature is superfluous) + let xs: [i32; 5] = [1, 2, 3, 4, 5]; + + // All elements can be initialized to the same value + let ys: [i32; 500] = [0; 500]; + + // Indexing starts at 0 + println!("first element of the array: {}", xs[0]); + println!("second element of the array: {}", xs[1]); + + // `len` returns the count of elements in the array + println!("number of elements in array: {}", xs.len()); + + // Arrays are stack allocated + println!("array occupies {} bytes", mem::size_of_val(&xs)); + + // Arrays can be automatically borrowed as slices + println!("borrow the whole array as a slice"); + analyze_slice(&xs); + + // Slices can point to a section of an array + // They are of the form [starting_index..ending_index] + // starting_index is the first position in the slice + // ending_index is one more than the last position in the slice + println!("borrow a section of the array as a slice"); + analyze_slice(&ys[1 .. 4]); +} + + +fn main() { + example1(); + example1b(); + example1c(); + example1d(); +} diff --git a/src/bin/example2.rs b/src/bin/example2.rs new file mode 100644 index 0000000..7b16354 --- /dev/null +++ b/src/bin/example2.rs @@ -0,0 +1,160 @@ +#![allow(dead_code)] +use std::mem; + +// https://doc.rust-lang.org/rust-by-example/custom_types/structs.html + +#[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 +struct Point { + x: f32, + y: f32, +} + +// Structs can be reused as fields of another struct +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 example2() { + // 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 { + top_left: Point { x: left_edge, y: top_edge }, + bottom_right: bottom_right, + // struct instantiation is an expression too + }; + + // 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); +} + +// https://doc.rust-lang.org/rust-by-example/custom_types/enum.html + +// Create an `enum` to classify a web event. Note how both +// names and type information together specify the variant: +// `PageLoad != PageUnload` and `KeyPress(char) != Paste(String)`. +// Each is different and independent. +enum WebEvent { + // An `enum` may either be `unit-like`, + PageLoad, + PageUnload, + // like tuple structs, + KeyPress(char), + Paste(String), + // or c-like structures. + Click { x: i64, y: i64 }, +} + +// A function which takes a `WebEvent` enum as an argument and +// returns nothing. +fn inspect(event: WebEvent) { + match event { + WebEvent::PageLoad => println!("page loaded"), + WebEvent::PageUnload => println!("page unloaded"), + // Destructure `c` from inside the `enum`. + WebEvent::KeyPress(c) => println!("pressed '{}'.", c), + WebEvent::Paste(s) => println!("pasted \"{}\".", s), + // Destructure `Click` into `x` and `y`. + WebEvent::Click { x, y } => { + println!("clicked at x={}, y={}.", x, y); + }, + } +} + +fn example2b() { + let pressed = WebEvent::KeyPress('x'); + // `to_owned()` creates an owned `String` from a string slice. + let pasted = WebEvent::Paste("my text".to_owned()); + let click = WebEvent::Click { x: 20, y: 80 }; + let load = WebEvent::PageLoad; + let unload = WebEvent::PageUnload; + + inspect(pressed); + inspect(pasted); + inspect(click); + inspect(load); + inspect(unload); +} + +// https://doc.rust-lang.org/rust-by-example/custom_types/enum/c_like.html +// enum with implicit discriminator (starts at 0) +enum Number { + Zero, + One, + Two, +} + + +// enum with explicit discriminator +enum Color { + Red = 0xff0000, + Green = 0x00ff00, + Blue = 0x0000ff, +} + + +fn example2c() { + // `enums` can be cast as integers. + println!("zero is {}", Number::Zero as i32); + println!("one is {}", Number::One as i32); + + println!("roses are #{:06x}", Color::Red as i32); + println!("violets are #{:06x}", Color::Blue as i32); +} + + +fn main() { + println!("Hello World! This is an APE built with Rust."); + example2(); + example2b(); + example2c(); + 0; +} diff --git a/src/main.rs b/src/bin/hello_world.rs similarity index 100% rename from src/main.rs rename to src/bin/hello_world.rs