rustbook

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit ce4fe05be848e1275080cb4d2ec8372f4171970f
Author: Charles Baptista <charles@charlesbaptista.com>
Date:   Fri, 26 Jun 2020 22:32:31 -0400

Initial Commit

Diffstat:
Aadder/.gitignore | 2++
Aadder/Cargo.toml | 9+++++++++
Aadder/src/lib.rs | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aadder/tests/intergration_test.rs | 6++++++
Acollect/.gitignore | 1+
Acollect/Cargo.lock | 5+++++
Acollect/Cargo.toml | 9+++++++++
Acollect/src/main.rs | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aenums/.gitignore | 1+
Aenums/Cargo.lock | 5+++++
Aenums/Cargo.toml | 9+++++++++
Aenums/src/main.rs | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aerrors/.gitignore | 1+
Aerrors/Cargo.lock | 5+++++
Aerrors/Cargo.toml | 9+++++++++
Aerrors/gello.txt | 1+
Aerrors/hello.txt | 0
Aerrors/src/main.rs | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Afizzbuzz/.gitignore | 1+
Afizzbuzz/Cargo.lock | 5+++++
Afizzbuzz/Cargo.toml | 9+++++++++
Afizzbuzz/src/main.rs | 16++++++++++++++++
Agenerics/.gitignore | 1+
Agenerics/Cargo.lock | 5+++++
Agenerics/Cargo.toml | 9+++++++++
Agenerics/src/main.rs | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aguessing_game/.gitignore | 1+
Aguessing_game/Cargo.lock | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aguessing_game/Cargo.toml | 10++++++++++
Aguessing_game/src/main.rs | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahello_cargo/.gitignore | 1+
Ahello_cargo/Cargo.lock | 5+++++
Ahello_cargo/Cargo.toml | 9+++++++++
Ahello_cargo/src/main.rs | 3+++
Alifetimes/.gitignore | 1+
Alifetimes/Cargo.lock | 5+++++
Alifetimes/Cargo.toml | 9+++++++++
Alifetimes/src/main.rs | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aminigrep/.gitignore | 1+
Aminigrep/Cargo.lock | 5+++++
Aminigrep/Cargo.toml | 9+++++++++
Aminigrep/src/lib.rs | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aminigrep/src/main.rs | 17+++++++++++++++++
Aownership/.gitignore | 1+
Aownership/Cargo.lock | 5+++++
Aownership/Cargo.toml | 9+++++++++
Aownership/src/main.rs | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apiglatin/.gitignore | 1+
Apiglatin/Cargo.lock | 5+++++
Apiglatin/Cargo.toml | 9+++++++++
Apiglatin/src/main.rs | 45+++++++++++++++++++++++++++++++++++++++++++++
Arectangles/.gitignore | 1+
Arectangles/Cargo.lock | 5+++++
Arectangles/Cargo.toml | 9+++++++++
Arectangles/src/main.rs | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arestaurant/.gitignore | 2++
Arestaurant/Cargo.toml | 9+++++++++
Arestaurant/src/front_of_house.rs | 9+++++++++
Arestaurant/src/front_of_house/hosting.rs | 4++++
Arestaurant/src/lib.rs | 43+++++++++++++++++++++++++++++++++++++++++++
Astructs/.gitignore | 1+
Astructs/Cargo.lock | 5+++++
Astructs/Cargo.toml | 9+++++++++
Astructs/src/main.rs | 43+++++++++++++++++++++++++++++++++++++++++++
Avars/.gitignore | 1+
Avars/Cargo.lock | 5+++++
Avars/Cargo.toml | 9+++++++++
Avars/src/main.rs | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
68 files changed, 1446 insertions(+), 0 deletions(-)

diff --git a/adder/.gitignore b/adder/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/adder/Cargo.toml b/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/adder/src/lib.rs b/adder/src/lib.rs @@ -0,0 +1,105 @@ +struct Rect { + w: u32, + h: u32, +} + +impl Rect { + fn fit(&self, other: &Rect) -> bool { + self.w > other.w && self.h > other.w + } +} + +pub fn greet(name: &str) -> String { + format!("Hail {}!", name) +} + +pub fn less_than_ten(val: i32) { + if val > 10 { + panic!("Value is too large"); + } +} + +pub fn add_two(a: i32) -> i32 { + add_internal(a, 2) +} + +fn add_internal(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal_test() { + assert_eq!(4, add_internal(2, 2)); + } + + #[test] + //expected filters for specific panic messages + #[should_panic(expected = "Value is too large")] + fn too_large() { + less_than_ten(11); + } + + #[test] + fn exploration() -> Result<(), String> { + if 2 + 2 == 4 { + Ok(()) + } else { + Err("test failure".to_string()) + } + } + + #[test] + #[ignore] + fn trollius() { + panic!("ert+576b"); + } + + #[test] + fn larger_fits_smaller() { + let large = Rect { + w: 10, + h: 10, + }; + + let small = Rect { + w:5, + h:5, + }; + + assert!(large.fit(&small)); + } + + #[test] + fn smaller_excludes_larger() { + let large = Rect { + w: 10, + h: 10, + }; + + let small = Rect { + w:5, + h:5, + }; + + assert!(!small.fit(&large)); + } + + #[test] + fn equality() { + assert_eq!(4, 2+2); + assert_ne!(4, 2+3); + } + + #[test] + fn has_name() { + let result = greet("Quintus"); + assert!(result.contains("Quintus"), + "Greeting did not contain name; result={}", + result + ); + } +} diff --git a/adder/tests/intergration_test.rs b/adder/tests/intergration_test.rs @@ -0,0 +1,6 @@ +use adder; + +#[test] +fn add_two() { + assert_eq!(4, adder::add_two(2)); +} diff --git a/collect/.gitignore b/collect/.gitignore @@ -0,0 +1 @@ +/target diff --git a/collect/Cargo.lock b/collect/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collect" +version = "0.1.0" diff --git a/collect/Cargo.toml b/collect/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "collect" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/collect/src/main.rs b/collect/src/main.rs @@ -0,0 +1,129 @@ +use std::collections::HashMap; + +fn print_all_elements(v: &Vec<i32>) { + for i in v { + println!("{}", i); + } +} + +fn beef_all_elements(v: &mut Vec<i32>) { + for i in v { + *i += 50; + println!("{}", i); + } +} + +enum Cell { + Int(i32), + Float(f64), + Text(String), +} + +fn main() { + let mut v: Vec<i32> = Vec::new(); + v.push(10); + v.push(20); + v.push(30); + v.push(40); + + let mut v2 = vec![1,2,3]; + v2.push(4); + v2.push(5); + v2.push(6); + v2.push(7); + + println!("v2[2]={}", &v2[2]); + println!("v2[3]={}", &v2[3]); + println!("v2[4]={}", &v2[4]); +// let does_net_exist = v2[100]); //Crash +// let does_net_exist = v2.get(100); + +// let first = &v2[0]; + v2.push(8); +// println!("first={}", first); Compile error firist is made invalid after push + + match v.get(2) { + Some(val) => println!("val={}", val), + None => println!("No entry at index"), + } + + print_all_elements(&v2); + beef_all_elements(&mut v2); + + let mut row: Vec<Cell> = Vec::new(); + row.push(Cell::Int(10)); + row.push(Cell::Float(12.6)); + row.push(Cell::Text(String::from("Frog"))); + + +// let mut s = String::new(); + let data = "Inital Contents"; + let mut s = data.to_string(); + + s.push_str(", some more content "); + + let s2 = "Make me a string".to_string(); + + s.push_str(&s2); + s.push('!'); + println!("{}", s); + println!("{}", s2); + + s = s + &s2; + println!("{}", s); + + let tic = "tic".to_string(); + let tac = "tac".to_string(); + let toe = "toe".to_string(); + + let ttt = format!("{}-{}-{}", tic, tac, toe); //Doesn't take ownerhship + let ttt2 = tic + "-" + &tac + "-" + &toe; //Takes owenership of tic + println!("{}", ttt); + println!("{}", ttt2); + + + let a = &ttt[5..6]; + println!("{}", a); + + for c in ttt.chars() { + println!("{}", c); + } + + for b in ttt.bytes() { + println!("{}", b); + } + + let mut scores = HashMap::new(); + + scores.insert(String::from("Red"), 10); + scores.insert(String::from("Blue"), 15); + + let teams = vec!["Blue".to_string(), "Red".to_string(), "Yellow".to_string(), "Green".to_string()]; + let starting_points = vec![10, 15, 3, 24]; + + let mut points: HashMap<String, i32> = teams.into_iter().zip(starting_points.into_iter()).collect(); + + let red_score = points.get(&"Red".to_string()); + if let Some(_) = red_score { + println!("red score: {:?}", red_score); + } + + points.insert("Red".to_string(), 1000); + points.entry("Red".to_string()).or_insert(2000); + points.entry("Orange".to_string()).or_insert(2000); + + for (key, value) in points { + println!("{} | {}", key, value); + } + + let text = "green ball red ball yellow ball blue ball"; + let mut wordcount = HashMap::new(); + + for word in text.split_whitespace() { + // if word doesn't exist set it to 0 + // if word does exist set c to be a reference to the value at word + let c = wordcount.entry(word).or_insert(0); + *c += 1; + } + println!("{:?}", wordcount); +} diff --git a/enums/.gitignore b/enums/.gitignore @@ -0,0 +1 @@ +/target diff --git a/enums/Cargo.lock b/enums/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" diff --git a/enums/Cargo.toml b/enums/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/enums/src/main.rs b/enums/src/main.rs @@ -0,0 +1,82 @@ +enum IpAddrKind { + V4, + V6, +} + +enum IpAddr { + V4(u8, u8, u8, u8), + V6(String), +} + +fn route(ip_type: IpAddrKind) {} + +#[derive(Debug)] +enum States { + MA, + RI, + NY, +} + +enum Coin { + Penny, + Nickel, + Dime, + Quarter(States), +} + +fn coin_val(coin: Coin) -> u8 { + match coin { + Coin::Penny => 1, + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter(state) => { + println!("State quarter from {:?}", state); + 25 + } + } +} + +fn plus_one(x: Option<u32>) -> Option<u32> { + match x { + Option::Some(i) => Some(i + 1), + Option::None => None, + } +} + +fn main() { + let four = IpAddrKind::V4; + let six = IpAddrKind::V6; + route(four); + route(six); +/* + let home = IpAddr { + kind: IpAddrKind::V4, + address: String::from("127.0.0.1"), + }; + + let loopback = IpAddr { + kind: IpAddrKind::V6, + address: String::from("::1"), + }; +*/ + + let home = IpAddr::V4(127, 0, 0, 1); + let loopback = IpAddr::V6(String::from("::1")); +/* + let n: i8 = 10; + let cat: Option<i8> = Some(5); +// let real = + let sum = cat + n; +*/ + println!("{}", coin_val(Coin::Quarter(States::MA))); + + let cat: Option<u32> = Some(10); + let not: Option<u32> = None; + println!("cat+1={:?}", plus_one(cat)); + println!("not+1={:?}", plus_one(not)); + + let n: Option<u32> = None; + if let None = n { + println!("n has no value!"); + } +} diff --git a/errors/.gitignore b/errors/.gitignore @@ -0,0 +1 @@ +/target diff --git a/errors/Cargo.lock b/errors/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "errors" +version = "0.1.0" diff --git a/errors/Cargo.toml b/errors/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "errors" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/errors/gello.txt b/errors/gello.txt @@ -0,0 +1 @@ +its reel! diff --git a/errors/hello.txt b/errors/hello.txt diff --git a/errors/src/main.rs b/errors/src/main.rs @@ -0,0 +1,49 @@ +use std::fs::File; +use std::io::ErrorKind; +use std::io::Read; +use std::io; + +fn main() { +// panic!("Mayday! Mayday!"); +// let v = vec![1, 2, 3]; +// v[99]; + + let f = File::open("hello.txt"); + let f = match f { + Result::Ok(file) => file, + Result::Err(error) => match error.kind() { + ErrorKind::NotFound => match File::create("hello.txt") { + Ok(fc) => fc, + Err(e) => panic!("Unable to create file: {:?}", e), + }, + other_error => panic!("Unable to open file: {:?}", other_error), + }, + }; + +// let g = File::open("gello.txt").unwrap(); +// let h = File::open("yello.txt").expect("Expect lets you write your own error message"); +// propagate_errors().unwrap(); + propagate_errors_shortstuff().unwrap(); +} + +fn propagate_errors() -> Result<String, io::Error> { + let f = File::open("not_real.txt"); + let mut f = match f { + Ok(file) => file, + Err(e) => return Err(e), + }; + + let mut s = String::new(); + + match f.read_to_string(&mut s) { + Ok(_) => Ok(s), + Err(e) => Err(e), + } +} + +fn propagate_errors_shortstuff() -> Result<String, io::Error> { + let mut f = File::open("not_real.txt")?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + Ok(s) +} diff --git a/fizzbuzz/.gitignore b/fizzbuzz/.gitignore @@ -0,0 +1 @@ +/target diff --git a/fizzbuzz/Cargo.lock b/fizzbuzz/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "fizzbuzz" +version = "0.1.0" diff --git a/fizzbuzz/Cargo.toml b/fizzbuzz/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "fizzbuzz" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/fizzbuzz/src/main.rs b/fizzbuzz/src/main.rs @@ -0,0 +1,16 @@ +fn main() { + let mut i = 0; + while i < 100 { + i += 1; + if(i % 3) == 0 { + print!("Fizz"); + } + if(i % 5) == 0 { + print!("Buzz"); + } + if((i % 5) != 0) && ((i % 3) != 0) { + print!("{}", i) + } + print!("\n"); + } +} diff --git a/generics/.gitignore b/generics/.gitignore @@ -0,0 +1 @@ +/target diff --git a/generics/Cargo.lock b/generics/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "generics" +version = "0.1.0" diff --git a/generics/Cargo.toml b/generics/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "generics" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/generics/src/main.rs b/generics/src/main.rs @@ -0,0 +1,129 @@ +use std::cmp::PartialOrd; +use std::fmt::Display; + +struct pt<T> { + x: T, + y: T, +} + +//impl for any pt +impl<T> pt<T> { + fn x(&self) -> &T { + &self.x + } +} + +//impl for only i32 pt +impl pt<i32> { + fn y(&self) -> &i32 { + &self.y + } +} + +struct wack<T, U> { + x: T, + y: U, +} + +//Blend wacks even with diferent types +impl<T, U> wack<T, U> { + fn blend<V, W>(self, other: wack<V, W>) -> wack<T, W> { + wack { + x: self.x, + y: other.y, + } + } +} + + +enum blam<T, U> { + Dwayne(T), + Wigan(U), +} + +pub trait Frobable { +// fn frob(&self) -> &str; //Just declare prototype + fn frob(&self) -> &str { + println!("This is the default if a type doesn't impl"); + "HELP!" + } +} + +pub struct Door { + x: i32, + y:i32, + target:String, +} + +impl Frobable for Door { + fn frob(&self) -> &str { + println!("Door target is {}", self.target); + &self.target + } +} + +pub struct Switch { + x: i32, + y: i32, + target:String, +} + +impl Frobable for Switch { + fn frob(&self) -> &str { + println!("Switch target is {}", self.target); + &self.target + } +} + +fn main() { + let list1 = vec![34, 50, 25, 100, 65]; + let list2 = vec![66, 94, 200, 13, 123]; + let list3 = vec!['!', 'A', ']', '@', 'b']; + max(&list1); + max(&list2); + max(&list3); + + let int_pt = pt{ x:1, y:4 }; + let float_pt = pt{ x: 1.2, y: 3.6 }; + float_pt.x; + int_pt.x; + let banana = wack{ x: 1, y: 1.0 }; + let mut who = blam::<i32, f64>::Dwayne(10); + let who = blam::<i32, f64>::Wigan(1.1); + + let d = Door { + x: 0, + y: 0, + target: "Over there".to_string(), + }; + d.frob(); + + let s = Switch { + x: 0, + y: 0, + target: "Over there".to_string(), + }; + s.frob(); + +} + +//fn max(list: &[i32]) { //Allows any i32 slice +//fn max(list: &Vec<i32>) { //Only Vectors +// +//Allows any vector of orderable, copyable, displayable types +//fn max<T: Display + PartialOrd + Copy>(list: &Vec<T>) { +// +//Alt of the above +fn max<T>(list: &Vec<T>) + where T: Display + PartialOrd + Copy, +{ + let mut max = list[0]; + + for &val in list { + if val > max { + max = val; + } + } + + println!("Max val={}", max); +} diff --git a/guessing_game/.gitignore b/guessing_game/.gitignore @@ -0,0 +1 @@ +/target diff --git a/guessing_game/Cargo.lock b/guessing_game/Cargo.lock @@ -0,0 +1,85 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/guessing_game/Cargo.toml b/guessing_game/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" diff --git a/guessing_game/src/main.rs b/guessing_game/src/main.rs @@ -0,0 +1,57 @@ +use std::io; +use rand::Rng; +use std::cmp::Ordering; + +pub struct Guess { + value: u32, +} + +impl Guess { + pub fn new(value: u32) -> Guess { + if value < 1 || value > 100 { + panic!("Guess is out of bounds (1-100)"); + } + Guess {value} + } + + pub fn get_value(&self) -> u32 { + self.value + } +} + +fn main() { + println!("Guess my number! (1-100)"); + let number = rand::thread_rng().gen_range(1, 101); + + loop { + println!("Input Guess:"); + + let mut guess = String::new(); + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + let guess = guess.trim(); + if guess == "quit" { + println!("quitting game!"); + break; + } + + let guess: Guess = match guess.parse() { + Ok(num) => Guess::new(num), + Err(_) => { + println!("{} is not a number!", guess); + continue; + } + }; + println!("Guess {} accepted!", guess.get_value()); + + match guess.get_value().cmp(&number) { + Ordering::Less => println!("Too Small!"), + Ordering::Greater=> println!("Too Large!"), + Ordering::Equal=> { + println!("Correct! The number is {}", number); + break; + } + } + } +} diff --git a/hello_cargo/.gitignore b/hello_cargo/.gitignore @@ -0,0 +1 @@ +/target diff --git a/hello_cargo/Cargo.lock b/hello_cargo/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_cargo" +version = "0.1.0" diff --git a/hello_cargo/Cargo.toml b/hello_cargo/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "hello_cargo" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/hello_cargo/src/main.rs b/hello_cargo/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/lifetimes/.gitignore b/lifetimes/.gitignore @@ -0,0 +1 @@ +/target diff --git a/lifetimes/Cargo.lock b/lifetimes/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "lifetimes" +version = "0.1.0" diff --git a/lifetimes/Cargo.toml b/lifetimes/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "lifetimes" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/lifetimes/src/main.rs b/lifetimes/src/main.rs @@ -0,0 +1,68 @@ +//This struct can only exist within the lifetime of 'part' +struct ImportantExcerpt<'a> { + part: &'a str, +} + +impl<'a> ImportantExcerpt<'a> { + fn level(&self) -> i32 { + 3 + } + + fn announce(&self, announcement: &str) -> &str { + println!("Attention please: {}", announcement); + self.part + } +} + +fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str { + if s1.len() > s2.len() { + s1 + } else { + s2 + } +} + +//Compiler can infer lifetime here, doesn't require explicit definition +fn first_word(s: &str) -> &str { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[0..i]; + } + } + &s[..] +} + +fn main() { + let string1 = String::from("abcd"); + { + let string2 = "xyz"; + let result = longest(string1.as_str(), string2); + println!("longest = {}", result); + } +// Complier error, lifetime is out of scope +// println!("longest = {}", result); + + let passage = String::from( + "It was the best of times. It was the worst of times." + ); + + let first = passage.split('.').next().expect("Failed to parse"); + let i = ImportantExcerpt { + part: first, + }; + + let s: &'static str = "static gives global lifetime"; + +/* + let r; + + { + let x = 5; + r = &x; + } + + println!("r: {}", r); +*/ +} diff --git a/minigrep/.gitignore b/minigrep/.gitignore @@ -0,0 +1 @@ +/target diff --git a/minigrep/Cargo.lock b/minigrep/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" diff --git a/minigrep/Cargo.toml b/minigrep/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/minigrep/src/lib.rs b/minigrep/src/lib.rs @@ -0,0 +1,108 @@ +use std::fs; +use std::error::Error; +use std::env; + +pub fn run(cf: Config) -> Result<(), Box<dyn Error>> { + let contents = fs::read_to_string(&cf.file)?; + let matches = if cf.case_sensitive { + search(&contents, &cf.pattern).unwrap() + } else { + search_case_insensitive(&contents, &cf.pattern).unwrap() + }; + + for i in matches { + println!("{}", i); + } + Ok(()) +} + +pub struct Config { + file: String, + pattern: String, + case_sensitive: bool, +} + +impl Config { + pub fn new(args: Vec<String>) -> Result<Config, &'static str> { + if args.len() < 3 { + return Err("not enough arguments"); + } + let file = args[1].clone(); + let pattern = args[2].clone(); + + let case_sensitive = env::var("CASE_SENSITIVE").is_err(); + Ok(Config { file, pattern, case_sensitive }) + } +} + +pub fn search_case_insensitive( + contents: &String, + pattern: &String +) -> Result<Vec<String>, Box<dyn Error>> { + let mut matches = Vec::new(); + let pattern = pattern.to_lowercase(); + + for line in contents.split("\n") { + if line.to_lowercase().contains(&pattern) { + matches.push(line.to_string()); + } + } + + Ok(matches) +} + + +pub fn search(contents: &String, pattern: &String) -> Result<Vec<String>, Box<dyn Error>> { + let mut matches = Vec::new(); + for line in contents.split("\n") { + if line.contains(pattern) { + matches.push(line.to_string()); + } + } + + Ok(matches) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic(expected = "not enough arguments")] + fn config_new_too_many_args() { + let args: Vec<String> = vec!["a".to_string(), "b".to_string()]; + Config::new(args).unwrap(); + } + + #[test] + fn simple_search() { + let l1 = "line 1 grepped here"; + let l2 = "line 2 skipped"; + let l3 = "line 3 grepped here"; + + let content = format!("{}\n{}\n{}\n", l1, l2, l3); + let pattern = "here".to_string(); + println!("{}", content); + + let matches = search(&content, &pattern).unwrap(); + assert_eq!(&matches[0], l1); + assert_eq!(&matches[1], l3); + } + + #[test] + fn case_sensitive() { + let content = "Lock the door\nBlock the door\n".to_string(); + let pattern = "lock".to_string(); + let matches = search(&content, &pattern).unwrap(); + assert_eq!(matches, vec!["Block the door"]); + } + + #[test] + fn case_insensitive() { + let content = "Lock the door\nBlock the door\n".to_string(); + let pattern = "lOcK".to_string(); + let matches = search_case_insensitive(&content, &pattern).unwrap(); + assert_eq!(matches, vec!["Lock the door", "Block the door"]); + } + +} diff --git a/minigrep/src/main.rs b/minigrep/src/main.rs @@ -0,0 +1,17 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec<String> = env::args().collect(); + + let cf = Config::new(args).unwrap_or_else(|err| { + eprintln!("Failed to parse arguments: {}", err); + process::exit(1); + }); + if let Err(e) = minigrep::run(cf) { + eprintln!("Application error: {}", e); + process::exit(1); + } +} diff --git a/ownership/.gitignore b/ownership/.gitignore @@ -0,0 +1 @@ +/target diff --git a/ownership/Cargo.lock b/ownership/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" diff --git a/ownership/Cargo.toml b/ownership/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/ownership/src/main.rs b/ownership/src/main.rs @@ -0,0 +1,84 @@ +fn main() { + let mut s = String::from("why hello there"); + s.push_str(" insect!"); + println!("{}", s); + + let x = 5; + just_copies(x); + let y = x; + println!("{}", y); + + let mut s1 = String::from("maggot!"); + s1 = takes_and_returns(s1); + let mut s2 = s1.clone(); + println!("s1={}, s2={}", s1, s2); + takes_ownership(s1); + + println!("s2.len = {}", get_length(&s2)); + println!("{}", s2); + + mut_ref(&mut s2); + println!("{}", s2); + + println!("first word={}", first_word(&s2)); + println!("3rd word={}", n_word(3, &s2)); +} + +fn takes_ownership(s: String) { + println!("You're Mine Now, {}", s); +} + +fn just_copies(x: u32) { + println!("scalars just get copied into the new scope: {}", x); +} + +fn takes_and_returns(mut s: String) -> String { + println!("You're Mine For Now, {}", s); + s.push_str(" I will throw you into the sun!"); + s +} + +fn get_length(s: &String) -> usize { + s.len() +} + +fn mut_ref(s: &mut String) { + s.push_str(" Scum!"); +} + +/* +fn dangler() -> &String { + let s = String::from("Spooky Ghost!"); + &s +} +*/ + +fn first_word(s: &str) -> &str { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[..i]; + } + } + + s +} + +fn n_word(n: u32, s: &String) -> &str { + let bytes = s.as_bytes(); + let mut j = 0; + let mut start = 0; + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + j += 1; + if j == n { + return &s[start..i]; + } + start = i; + } + } + + s +} diff --git a/piglatin/.gitignore b/piglatin/.gitignore @@ -0,0 +1 @@ +/target diff --git a/piglatin/Cargo.lock b/piglatin/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "piglatin" +version = "0.1.0" diff --git a/piglatin/Cargo.toml b/piglatin/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "piglatin" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/piglatin/src/main.rs b/piglatin/src/main.rs @@ -0,0 +1,45 @@ +use std::io; + +fn is_vowel(c: &char) -> bool { + match c { + 'a' => true, + 'e' => true, + 'i' => true, + 'o' => true, + 'u' => true, + 'A' => true, + 'E' => true, + 'I' => true, + 'O' => true, + 'U' => true, + _ => false, + } +} + +fn main() { + + println!("Enter text to pig-latinize:"); + let mut text = String::new(); + io::stdin() + .read_line(&mut text) + .expect("Failed to read line"); + let text = text.trim(); + let mut p_text = String::new(); + + for w in text.split_whitespace() { + let mut pig_w; + let first = w.chars().next().unwrap(); + if is_vowel(&first) { + pig_w = w.to_string(); + pig_w.push_str("-tay"); + } else { + pig_w = w[1..].to_string(); + pig_w.push('-'); + pig_w.push(first); + pig_w.push_str("ay"); + } + p_text.push_str(&pig_w[..]); + p_text.push(' '); + } + println!("{}", p_text); +} diff --git a/rectangles/.gitignore b/rectangles/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rectangles/Cargo.lock b/rectangles/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/rectangles/Cargo.toml b/rectangles/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rectangles" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rectangles/src/main.rs b/rectangles/src/main.rs @@ -0,0 +1,59 @@ +#[derive(Debug)] +struct Rect { + h: u16, + w: u16, +} + +impl Rect { + fn area(&self) -> u16 { + self.w * self.h + } + + fn fit(&self, fit: &Rect) -> bool { + self.w > fit.w && self.h > fit.h + } + + fn square(size: u16) -> Rect { + Rect { + h: size, + w: size, + } + } +} + +struct Rectuple (u16, u16); + +fn rectuple_area(rect: Rectuple) -> u16 { + rect.0 * rect.1 +} + +fn calc_area(rect: &Rect) -> u16 { + rect.h * rect.w +} + +fn main() { + let rect1 = Rect { + h: 10, + w: 20, + }; + + let result = calc_area(&rect1); + println!("area1={}", result); + + let rect3 = Rectuple(15, 20); + println!("area2={}", rectuple_area(rect3)); + + println!("rect1={:#?}", rect1); + println!("area from private method={}", rect1.area()); + + let rect2 = Rect { + h: 12, + w: 22, + }; + + let square = Rect::square(10); + println!("square={:#?}", square); + + println!("Does rect1 fit in rect2? {}!", rect2.fit(&rect1)); + println!("Does rect2 fit in rect1? {}!", rect1.fit(&rect2)); +} diff --git a/restaurant/.gitignore b/restaurant/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/restaurant/Cargo.toml b/restaurant/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/restaurant/src/front_of_house.rs b/restaurant/src/front_of_house.rs @@ -0,0 +1,9 @@ +pub mod hosting; + +pub mod serving { + fn take_order() {} + + pub fn serve_order() {} + + fn take_payment() {} +} diff --git a/restaurant/src/front_of_house/hosting.rs b/restaurant/src/front_of_house/hosting.rs @@ -0,0 +1,4 @@ +pub fn add_to_waitlist() {} + +fn seat_at_table() {} + diff --git a/restaurant/src/lib.rs b/restaurant/src/lib.rs @@ -0,0 +1,43 @@ +pub mod front_of_house; + +pub mod back_of_house { + pub enum Appetizer { + Soup, + Salad, + } + + pub struct Breakfast { + pub toast: String, + fruit: String, + } + + impl Breakfast { + pub fn summer(toast: &str) -> Breakfast { + Breakfast { + toast: String::from(toast), + fruit: String::from("peaches"), + } + } + } + + pub fn fix_order () { + cook_order(); + super::front_of_house::serving::serve_order(); + } + + fn cook_order() {} +} + +pub fn eat_at_restaurant() { + use front_of_house::hosting; + use back_of_house::fix_order as fix; + fix(); + hosting::add_to_waitlist(); + + let mut meal = back_of_house::Breakfast::summer("rye"); + meal.toast = String::from("brown"); + + let order1 = back_of_house::Appetizer::Soup; + let order2 = back_of_house::Appetizer::Salad; +// meal.fruit = String::from("kiwi"); +} diff --git a/structs/.gitignore b/structs/.gitignore @@ -0,0 +1 @@ +/target diff --git a/structs/Cargo.lock b/structs/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" diff --git a/structs/Cargo.toml b/structs/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/structs/src/main.rs b/structs/src/main.rs @@ -0,0 +1,43 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +fn new_user(email: String, username: String) -> User { + User { + email, // == email: email, because names match + username, //== username: username, + sign_in_count: 0, + active: false, + } +} + +struct rgb(u16, u16, u16); +struct point(u16, u16, u16); + +fn main() { + let mut user1 = User { + username: String::from("strongbad"), + email: String::from("strongbad@homestarrunner.com"), + sign_in_count: 1, + active: true, + }; + + println!("email={}", user1.email); + user1.email = String::from("djmankewicz@homestarrunner.com"); + println!("email={}", user1.email); + + let user2 = new_user(String::from("gunship@hegemon.com"), String::from("champeener") ); + println!("email={}", user2.email); + + let user3 = User { + email: String::from("systemerror@paradise.com"), + ..user2 + }; + println!("email={}", user3.email); + + let white = rgb(255, 255, 255); + let origin = point(0, 0, 0); +} diff --git a/vars/.gitignore b/vars/.gitignore @@ -0,0 +1 @@ +/target diff --git a/vars/Cargo.lock b/vars/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "vars" +version = "0.1.0" diff --git a/vars/Cargo.toml b/vars/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "vars" +version = "0.1.0" +authors = ["Charles Baptista <charles@charlesbaptista.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/vars/src/main.rs b/vars/src/main.rs @@ -0,0 +1,76 @@ +fn main() { + let x = 5; + println!("x={}", x); + let x = x + 1; + println!("x={}", x); + let x = x * 2; + println!("x={}", x); + + + let y = 2.0; + let z: f32 = 3.0; + let c = 'n'; + println!("y={}, z={}, c={}", y,z,c); + + let tp: (i32, f64, u8) = (500, 343.33, 3); + let (q, w, e) = tp; + println!("tp: {}, {}, {}", q, w, e); + let r = tp.2; + println!("tp.2={}", r); + + let a = [1, 2, 3, 4, 5]; + println!("a[3]={}", a[3]); + + let a: [u32; 3] = [6, 7, 8]; + println!("a[2]={}", a[2]); + + let a = [0; 5]; + println!("a[2]={}", a[2]); + + another_function(); + println!("a&p returns {}", add_and_print(x,x)); + + //Welcome to the land of flow control + + let b = true; + let test = if b {5} else {6}; + println!("test={}", test); + + let mut i = 0; + while i < 10 { + if i < 5 { + println!("flow 1"); + } else if i == 5 { + println!("flow 2"); + } else { + println!("flow 3"); + } + i += 1; + } + + let mut looper = 0; + let count = loop { + looper += 1; + if looper == 10 { + break looper; + } + }; + println!("count={}", count); + + for element in a.iter() { + println!("element={}", element); + } + + for cd in (1..4).rev() { + println!("{}", cd); + } +} + +fn another_function() { + println!("This is how to declare and call a function"); +} + +fn add_and_print(x: u32, y: u32) -> u32 { + println!("the number is {}", x+y); + x+y +}