Add example files
This commit is contained in:
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
**/target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
**/Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# Generated by VS Code
|
||||
**/.vscode
|
||||
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"examples/cafeteria",
|
||||
"examples/hello",
|
||||
"examples/kitchen",
|
||||
"examples/puzzle_game",
|
||||
"examples/puzzles",
|
||||
]
|
||||
1
examples/cafeteria/.gitignore
vendored
Normal file
1
examples/cafeteria/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
8
examples/cafeteria/Cargo.toml
Normal file
8
examples/cafeteria/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "cafeteria"
|
||||
version = "0.1.0"
|
||||
authors = ["Nathan Stocks <nathan@agileperception.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
crossbeam = "0.8"
|
||||
57
examples/cafeteria/src/main.rs
Normal file
57
examples/cafeteria/src/main.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
use crossbeam::channel::{self, Receiver, Sender};
|
||||
use std::{thread, time::Duration};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Lunch {
|
||||
Soup,
|
||||
Salad,
|
||||
Sandwich,
|
||||
HotDog,
|
||||
}
|
||||
|
||||
fn cafeteria_worker(name: &str, orders: Receiver<&str>, lunches: Sender<Lunch>) {
|
||||
for order in orders {
|
||||
println!("{} receives an order for {}", name, order);
|
||||
let lunch = match &order {
|
||||
x if x.contains("soup") => Lunch::Soup,
|
||||
x if x.contains("salad") => Lunch::Salad,
|
||||
x if x.contains("sandwich") => Lunch::Sandwich,
|
||||
_ => Lunch::HotDog,
|
||||
};
|
||||
for _ in 0..order.len() {
|
||||
thread::sleep(Duration::from_secs_f32(0.1))
|
||||
}
|
||||
println!("{} sends a {:?}", name, lunch);
|
||||
if lunches.send(lunch).is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (orders_tx, orders_rx) = channel::unbounded();
|
||||
let orders_rx2 = orders_rx.clone();
|
||||
let (lunches_tx, lunches_rx) = channel::unbounded();
|
||||
let lunches_tx2 = lunches_tx.clone();
|
||||
|
||||
let alice_handle = thread::spawn(|| cafeteria_worker("alice", orders_rx2, lunches_tx2));
|
||||
let zack_handle = thread::spawn(|| cafeteria_worker("zack", orders_rx, lunches_tx));
|
||||
|
||||
for order in vec![
|
||||
"polish dog",
|
||||
"caesar salad",
|
||||
"onion soup",
|
||||
"reuben sandwich",
|
||||
] {
|
||||
println!("ORDER: {}", order);
|
||||
let _ = orders_tx.send(order);
|
||||
}
|
||||
drop(orders_tx);
|
||||
|
||||
for lunch in lunches_rx {
|
||||
println!("Order Up! -> {:?}", lunch);
|
||||
}
|
||||
|
||||
let _ = alice_handle.join();
|
||||
let _ = zack_handle.join();
|
||||
}
|
||||
14
examples/hello/Cargo.toml
Normal file
14
examples/hello/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "hello"
|
||||
version = "0.1.0"
|
||||
authors = ["Nathan Stocks <nathan@agileperception.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = { version = "0.3", features = ["html_reports"] }
|
||||
|
||||
[[bench]]
|
||||
name = "snuggle_speed"
|
||||
harness = false
|
||||
9
examples/hello/benches/snuggle_speed.rs
Normal file
9
examples/hello/benches/snuggle_speed.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use hello::snuggle;
|
||||
|
||||
pub fn snuggle_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("snuggle 2", |b| b.iter(|| snuggle(black_box(2))));
|
||||
}
|
||||
|
||||
criterion_group!(benches, snuggle_benchmark);
|
||||
criterion_main!(benches);
|
||||
35
examples/hello/src/lib.rs
Normal file
35
examples/hello/src/lib.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use hello::snuggle;
|
||||
/// let bunnies = snuggle(5);
|
||||
/// assert_eq!(bunnies, 40);
|
||||
/// ```
|
||||
pub fn snuggle(bunnies: u128) -> u128 {
|
||||
bunnies << 3
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::num::ParseIntError;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn snuggling_bunnies_multiply() {
|
||||
assert_eq!(snuggle(2), 16);
|
||||
}
|
||||
|
||||
#[should_panic]
|
||||
#[test]
|
||||
fn scared_bunny() {
|
||||
panic!("Hop hoppity hop!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bunny_result() -> Result<(), ParseIntError> {
|
||||
let num_bunnies: u64 = "4".parse()?;
|
||||
assert_eq!(num_bunnies, 4);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
10
examples/hello/src/main.rs
Normal file
10
examples/hello/src/main.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
#[test]
|
||||
fn the_bin_test() {
|
||||
assert_eq!(1 + 1, 2);
|
||||
}
|
||||
}
|
||||
6
examples/hello/tests/anything.rs
Normal file
6
examples/hello/tests/anything.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use hello::snuggle;
|
||||
|
||||
#[test]
|
||||
fn it_works_from_outside() {
|
||||
assert!(snuggle(4) == 32);
|
||||
}
|
||||
9
examples/kitchen/Cargo.toml
Normal file
9
examples/kitchen/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "kitchen"
|
||||
version = "0.1.0"
|
||||
authors = ["Nathan Stocks <nathan@agileperception.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
env_logger = "0.8"
|
||||
43
examples/kitchen/src/main.rs
Normal file
43
examples/kitchen/src/main.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use log::{error, info};
|
||||
use std::{thread, time::Duration};
|
||||
|
||||
fn sleep(seconds: f32) {
|
||||
thread::sleep(Duration::from_secs_f32(seconds));
|
||||
}
|
||||
|
||||
pub mod dad {
|
||||
use super::{info, sleep};
|
||||
|
||||
pub fn cook_spaghetti() -> bool {
|
||||
info!("Cooking the spaghetti...");
|
||||
sleep(4.0);
|
||||
info!("Spaghetti is ready!");
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub mod mom {
|
||||
use super::{info, sleep};
|
||||
|
||||
pub fn cook_sauce_and_set_table() {
|
||||
sleep(1.0);
|
||||
info!("Cooking the sauce...");
|
||||
sleep(2.0);
|
||||
info!("Sauce is ready! Setting the table...");
|
||||
sleep(2.0);
|
||||
info!("Table is set!");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let handle = thread::spawn(|| dad::cook_spaghetti());
|
||||
|
||||
mom::cook_sauce_and_set_table();
|
||||
|
||||
if handle.join().unwrap_or(false) {
|
||||
info!("Spaghetti time! Yum!")
|
||||
} else {
|
||||
error!("Dad messed up the spaghetti. Order pizza instead?");
|
||||
}
|
||||
}
|
||||
1
examples/puzzle_game/.gitignore
vendored
Normal file
1
examples/puzzle_game/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
11
examples/puzzle_game/Cargo.toml
Normal file
11
examples/puzzle_game/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "puzzle_game"
|
||||
version = "0.1.0"
|
||||
authors = ["Nathan Stocks <nathan@agileperception.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
puzzles = { path = "../puzzles" }
|
||||
log = "0.4"
|
||||
env_logger = "0.8"
|
||||
1
examples/puzzle_game/puzzle.dat
Normal file
1
examples/puzzle_game/puzzle.dat
Normal file
@@ -0,0 +1 @@
|
||||
this is a puzzle
|
||||
21
examples/puzzle_game/src/main.rs
Normal file
21
examples/puzzle_game/src/main.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
use anyhow::{Context, Result};
|
||||
use log::info;
|
||||
use puzzles::Puzzle;
|
||||
use std::fs::File;
|
||||
|
||||
fn get_puzzle(filename: &str) -> Result<Puzzle> {
|
||||
let fh = File::open(filename)
|
||||
.with_context(|| format!("couldn't open the puzzle file {}", filename))?;
|
||||
let puzzle = Puzzle::from_file(fh).context("couldn't convert data into a puzzle")?;
|
||||
Ok(puzzle)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
env_logger::init();
|
||||
let puzzle = match get_puzzle("puzzle.dat").context("Couldn't get the first puzzle") {
|
||||
Ok(p) => p,
|
||||
Err(_) => Puzzle::new(),
|
||||
};
|
||||
info!("Playing puzzle: {}", puzzle.name);
|
||||
Ok(())
|
||||
}
|
||||
1
examples/puzzles/.gitignore
vendored
Normal file
1
examples/puzzles/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
9
examples/puzzles/Cargo.toml
Normal file
9
examples/puzzles/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "puzzles"
|
||||
version = "0.1.0"
|
||||
authors = ["Nathan Stocks <nathan@agileperception.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
thiserror = "1.0"
|
||||
log = "0.4"
|
||||
183
examples/puzzles/src/lib.rs
Normal file
183
examples/puzzles/src/lib.rs
Normal file
@@ -0,0 +1,183 @@
|
||||
use log::{error, info};
|
||||
use std::fs::File;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Number of pieces in the puzzle
|
||||
///
|
||||
/// # History
|
||||
///
|
||||
/// This is a separate paragraph.
|
||||
/// - Clickable link: [PUZZLE_PIECES]
|
||||
/// - We tried `7`, but this is better
|
||||
pub const PUZZLE_PIECES: u32 = 42;
|
||||
|
||||
/// This is a Puzzle!
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Puzzle {
|
||||
/// Number of pieces
|
||||
pub num_pieces: u32,
|
||||
/// Descriptive name
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Puzzle {
|
||||
/// Make a new puzzle!
|
||||
pub fn new() -> Self {
|
||||
let puzzle = Default::default();
|
||||
info!("Created a puzzle with new(): {:?}", puzzle);
|
||||
puzzle
|
||||
}
|
||||
/// Load a puzzle from a file
|
||||
pub fn from_file(_fh: File) -> Result<Self, PuzzleError> {
|
||||
error!("This file is missing a piece!");
|
||||
Err(PuzzleError::MissingPiece)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Puzzle {
|
||||
fn default() -> Self {
|
||||
Puzzle {
|
||||
num_pieces: PUZZLE_PIECES,
|
||||
name: "Forest Lake".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Puzzle {
|
||||
fn eq(self: &Puzzle, other: &Puzzle) -> bool {
|
||||
(self.num_pieces == other.num_pieces)
|
||||
&& (self.name.to_lowercase() == other.name.to_lowercase())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Puzzle> for String {
|
||||
fn from(puzzle: &Puzzle) -> Self {
|
||||
puzzle.name.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn show<T: Into<String>>(s: T) {
|
||||
println!("{}", s.into());
|
||||
}
|
||||
|
||||
pub fn blah() {
|
||||
let puzzle = Puzzle::default();
|
||||
show(&puzzle);
|
||||
// puzzle is still available!
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum PuzzleType {
|
||||
Jigsaw,
|
||||
}
|
||||
|
||||
// struct Vehicle;
|
||||
// enum TransformerError {
|
||||
// Whatever,
|
||||
// }
|
||||
|
||||
// struct Transformer;
|
||||
// impl Transformer {
|
||||
// pub fn new() -> Self {
|
||||
// Self {}
|
||||
// }
|
||||
// pub fn stand(self) -> Result<Transformer, TransformerError> {
|
||||
// Ok(self)
|
||||
// }
|
||||
// pub fn transform(self) -> Result<Transformer, TransformerError> {
|
||||
// Ok(self)
|
||||
// }
|
||||
// pub fn rollout(self) -> Result<Transformer, TransformerError> {
|
||||
// Ok(self)
|
||||
// }
|
||||
// pub fn chase(self) -> Result<Transformer, TransformerError> {
|
||||
// Ok(self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn autobots_rollout() -> Result<Vehicle, TransformerError> {
|
||||
// let optimus = Transformer::new();
|
||||
// try!(try!(try!(try!(optimus.stand()).transform()).rollout()).chase())
|
||||
// // optimus.stand()?.transform()?.rollout()?.chase()?
|
||||
// }
|
||||
|
||||
// optimus.stand()?.transform()?.rollout()?.chase()?
|
||||
|
||||
// let stand = match optimus.stand() {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// };
|
||||
// let transform = match stand.transform() {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// };
|
||||
// let rollout = match transform.rollout() {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// };
|
||||
// match transform.chase() {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// };
|
||||
|
||||
// match {
|
||||
// match {
|
||||
// match {
|
||||
// match optimus.stand() {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// }
|
||||
// }
|
||||
// .transform()
|
||||
// {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// }
|
||||
// }
|
||||
// .rollout()
|
||||
// {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// }
|
||||
// }
|
||||
// .chase()
|
||||
// {
|
||||
// Ok(x) => x,
|
||||
// Err(e) => return Err(e),
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[derive(Debug)] // #5: Debug + Display + Exception
|
||||
// #[non_exhaustive] // #4: Non-Exhaustive
|
||||
// pub enum PuzzleError {
|
||||
// // #1: enum
|
||||
// WontFit(u16), // #2: Group Errors
|
||||
// MissingPiece, // #3: Only YOUR Errors
|
||||
// }
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum PuzzleError {
|
||||
#[error("Piece {0} doesn't fit!")]
|
||||
WontFit(u16),
|
||||
#[error("Missing a piece")]
|
||||
MissingPiece,
|
||||
}
|
||||
|
||||
// impl Display for PuzzleError {
|
||||
// // #5: Debug + Display + Exception
|
||||
// fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
// use PuzzleError::*;
|
||||
// match self {
|
||||
// MissingPiece => write!(f, "Missing a piece"),
|
||||
// WontFit(n) => write!(f, "Piece {} doesn't fit!", n),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl Error for PuzzleError {
|
||||
// // #5: Debug + Display + Exception
|
||||
// fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
7
examples/puzzles/src/main.rs
Normal file
7
examples/puzzles/src/main.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
use puzzles::{blah, Puzzle, PuzzleError};
|
||||
|
||||
fn main() {
|
||||
blah();
|
||||
}
|
||||
Reference in New Issue
Block a user