Compare commits

..

8 Commits

13 changed files with 251 additions and 113 deletions

View File

@@ -6,30 +6,31 @@ fn main() {
// number multiplied by itself), and assign the closure to the "square" variable. Then run the // number multiplied by itself), and assign the closure to the "square" variable. Then run the
// code and make sure it works. // code and make sure it works.
// let square = ... let square = |x| x * x;
// println!("5 squared is {}", square(5)); println!("5 squared is {}", square(5));
// 2. Uncomment the code below. Finish the .map() iterator adaptor call by passing it a closure // 2. Uncomment the code below. Finish the .map() iterator adaptor call by passing it a closure
// which takes a tuple of two integers as a parameter, and returns a tuple with the first // which takes a tuple of two integers as a parameter, and returns a tuple with the first
// integer incremented by 1, and the second integer left alone. For example, if given the input // integer incremented by 1, and the second integer left alone. For example, if given the input
// (0, 1), it should return (1, 1). Run the code and make sure it works. // (0, 1), it should return (1, 1). Run the code and make sure it works.
// let pairs = vec![(0, 1), (2, 3), (4, 5)]; let pairs = vec![(0, 1), (2, 3), (4, 5)];
// pairs pairs
// .into_iter() .into_iter()
// .map( ... ) .map(|t| (t.0 + 1, t.1))
// .for_each(|t| println!("{:?}", t)); .for_each(|t| println!("{:?}", t));
// 3. Uncomment the code below. There is a mutable vector named `numbers`. Use an iterator over // 3. Uncomment the code below. There is a mutable vector named `numbers`. Use an iterator over
// mutable references to multiply each of the values in `numbers` by 3. // mutable references to multiply each of the values in `numbers` by 3.
// Hint 1: You'll need .iter_mut() -- bonus points if you use the shorter, syntactic sugar form! // Hint 1: You'll need .iter_mut() -- bonus points if you use the shorter, syntactic sugar form!
// Hint 2: `x` will be a mutable reference, so remember to dereference it to use it // Hint 2: `x` will be a mutable reference, so remember to dereference it to use it
// let mut numbers = vec![1, 2, 3, 4]; let mut numbers = vec![1, 2, 3, 4];
// for x in ... { // numbers = numbers.iter_mut().map(|x| *x * 3).collect();
// ... // multiply the value by 3 via the mutable reference x for n in &mut numbers {
// } *n = *n * 3;
// println!("{:?}", numbers); // should print [3, 6, 9, 12] }
println!("{:?}", numbers); // should print [3, 6, 9, 12]
// 4. Uncomment the code below. Take the vector of words and // 4. Uncomment the code below. Take the vector of words and
// - Convert the vector into an iterator with .into_iter() // - Convert the vector into an iterator with .into_iter()
@@ -39,9 +40,13 @@ fn main() {
// //
// Hint: .to_uppercase() is a method on `str` which returns a String // Hint: .to_uppercase() is a method on `str` which returns a String
// let words = vec!["autobot", "beach", "car", "decepticon", "energon", "frothy"]; let words = vec!["autobot", "beach", "car", "decepticon", "energon", "frothy"];
// let transformed... // do the stuff here let transformed = words
// println!("Transformed: {:?}", transformed); .into_iter()
.filter(|w| !w.contains("h"))
.map(|w| w.to_uppercase())
.collect::<Vec<String>>();
println!("Transformed: {:?}", transformed);
// Challenge: // Challenge:
// //

View File

@@ -4,10 +4,17 @@
// //
// Once you've got the documentation here, run `cargo doc --no-deps --open` and take a look! // Once you've got the documentation here, run `cargo doc --no-deps --open` and take a look!
//! A pumpkin is a cultivated winter squash in the genus Cucurbita.
//! The term is most commonly applied to round, orange-colored squash varieties,
//! but does not possess a scientific definition. It may be used in reference to
//! many different squashes of varied appearance and belonging to multiple species in the Cucurbita genus.
// 2. What about an image!? Add an image of a pumpkin to the end of the module-level documentation. // 2. What about an image!? Add an image of a pumpkin to the end of the module-level documentation.
// The markdown format is ![some alt text](https://url-to-the-image.png) // The markdown format is ![some alt text](https://url-to-the-image.png)
// Here's the image to link to: https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/FrenchMarketPumpkinsB.jpg/700px-FrenchMarketPumpkinsB.jpg // Here's the image to link to: https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/FrenchMarketPumpkinsB.jpg/700px-FrenchMarketPumpkinsB.jpg
//! ![Pumpkin Image](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/FrenchMarketPumpkinsB.jpg/700px-FrenchMarketPumpkinsB.jpg)
// 3. Document the Pumpkin struct. // 3. Document the Pumpkin struct.
// - The description on the index page should be "Big orange thing" // - The description on the index page should be "Big orange thing"
// - Make a section header called "Recipes" // - Make a section header called "Recipes"
@@ -15,8 +22,16 @@
// - Document the "roundness" field, explaining that it is a percentage // - Document the "roundness" field, explaining that it is a percentage
// - Document the "orangeness" field, explaining that it is a number from 8 to 27 // - Document the "orangeness" field, explaining that it is a number from 8 to 27
/// Big orange thing
///
/// # Recipes
///
/// Recipes will be coming soon.
pub struct Pumpkin { pub struct Pumpkin {
/// `roundness` is a percentage that describes how round the pumpkin is.
/// 100% means perfectly round, while 0% means not round at all.
pub roundness: f32, pub roundness: f32,
/// `orangeness` is a number from 8 to 27 that describes how orange the pumpkin is.
pub orangeness: i32, pub orangeness: i32,
} }
@@ -24,12 +39,14 @@ pub struct Pumpkin {
// can't be used for pie. :'-( // can't be used for pie. :'-(
impl Pumpkin { impl Pumpkin {
/// Smash the pumpkin. Once smashed, it cannot be used for pie.
pub fn smash(self) {} pub fn smash(self) {}
} }
// 5. Document that BURNT_ORANGE is for the "orangeness" field in the Pumpkin struct. // 5. Document that BURNT_ORANGE is for the "orangeness" field in the Pumpkin struct.
// - Link to the Pumpkin struct in your description // - Link to the Pumpkin struct in your description
/// The `BURNT_ORANGE` constant is a value of 13 that can be used for the `orangeness` field in the [Pumpkin] struct.
pub const BURNT_ORANGE: i32 = 13; pub const BURNT_ORANGE: i32 = 13;
// Challenge: Find the option to pass to `cargo doc` so that documentation for this private item // Challenge: Find the option to pass to `cargo doc` so that documentation for this private item

View File

@@ -14,7 +14,18 @@
// Once you have completed defining the error type correctly, you should be able to run // Once you have completed defining the error type correctly, you should be able to run
// `cargo build --lib` without any build errors or warnings. Then go to main.rs and continue with #2 // `cargo build --lib` without any build errors or warnings. Then go to main.rs and continue with #2
// pub enum DolphinError... use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum DolphinError {
#[error("The dolphin is hungry")]
Hungry,
#[error("The dolphin is too young")]
TooYoung,
#[error("The dolphin's name is too long and annoying to say")]
LongName,
}
pub struct Dolphin { pub struct Dolphin {
pub name: String, pub name: String,

View File

@@ -3,30 +3,32 @@
use aquarium::Dolphin; use aquarium::Dolphin;
// Silence some warnings so they don't distract from the exercise. // Silence some warnings so they don't distract from the exercise.
#[allow(clippy::vec_init_then_push)] #[allow(clippy::vec_init_then_push)]
// (You already did #1 in lib.rs, right?) // (You already did #1 in lib.rs, right?)
// //
// 2a. Uncomment and finish the play_time function below // 2a. Uncomment and finish the play_time function below
// - Bring anyhow::Result into scope with a `use` statement // - Bring anyhow::Result into scope with a `use` statement
// - Have the play_time function return a `Result<Vec<String>>`. The vector of Strings will // - Have the play_time function return a `Result<Vec<String>>`. The vector of Strings will
// represent successful outcomes of various dolphin tricks. // represent successful outcomes of various dolphin tricks.
use anyhow::Result;
// fn play_time(dolphin: &Dolphin) -> ... { fn play_time(dolphin: &Dolphin) -> Result<Vec<String>> {
// let mut responses = vec![]; let mut responses = vec![];
// // 2b. Call the .say_your_name() method on `dolphin`, use `?` to unwrap the value, and push // 2b. Call the .say_your_name() method on `dolphin`, use `?` to unwrap the value, and push
// // the value onto the `responses` vector. // the value onto the `responses` vector.
// // //
// // let response = ... // this can be done with an intermediate variable... let response = dolphin.say_your_name()?; // this can be done with an intermediate variable...
// // responses.push( ... ) // ...or all on one line. Either way is fine! responses.push(response); // ...or all on one line. Either way is fine!
// // //
// // 2c. Do the same thing as #2b for the .flip() method // 2c. Do the same thing as #2b for the .flip() method
// // responses.push(dolphin.flip()?);
// // 2d. Do the same thing as #2b for the .shake_hands() method //
// // 2d. Do the same thing as #2b for the .shake_hands() method
// Ok(responses) responses.push(dolphin.shake_hands()?);
// }
fn main() { Ok(responses)
}
fn main() -> Result<()> {
let dolphins = vec![ let dolphins = vec![
Dolphin { Dolphin {
name: "Augustinius".into(), name: "Augustinius".into(),
@@ -57,14 +59,23 @@ fn main() {
// returns an Err variant the first time it is called, the try operator will return it from // returns an Err variant the first time it is called, the try operator will return it from
// main(), which will end the program at the first error. anyhow's Result will take care of // main(), which will end the program at the first error. anyhow's Result will take care of
// formatting the error output for us. // formatting the error output for us.
match play_time(dolphin) { match play_time(dolphin) {
Ok(responses) => { Ok(responses) => {
println!("{} did a FABULOUS PERFORMANCE!", dolphin.name); println!("\n{} did a FABULOUS PERFORMANCE!", dolphin.name);
for response in responses { for response in responses {
println!(" {}", response); println!(" {}", response);
} }
} }
Err(e) => println!("{} can't perform today: {}", dolphin.name, e.to_string()), Err(e) => println!("{} can't perform today: {}", dolphin.name, e.to_string()),
} }
// let responses = play_time(dolphin)?;
// println!("\n{} did a FABULOUS PERFORMANCE!", dolphin.name);
// for response in responses {
// println!(" {}", response);
// }
} }
Ok(())
} }

View File

@@ -4,10 +4,5 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
# I'm glad you came to add the `log` dependency! I got it all ready for you, just uncomment: log = "0.4" # I'm glad you came to add the `log` dependency! I got it all ready for you, just uncomment:
# env_logger = "0.9" # And here's the env_logger dependency that you'll need in main.rs
# log = "0.4"
# And here's the env_logger dependency that you'll need in main.rs
#
# env_logger = "0.9"

View File

@@ -6,6 +6,8 @@
// //
// Hint: You need to update Cargo.toml to add the `log` dependency, first. // Hint: You need to update Cargo.toml to add the `log` dependency, first.
use log::{debug, error, info, trace, warn};
#[derive(Debug)] #[derive(Debug)]
pub struct Frog { pub struct Frog {
energy: u8, energy: u8,
@@ -15,19 +17,23 @@ pub struct Frog {
impl Frog { impl Frog {
pub fn new() -> Self { pub fn new() -> Self {
// 2. Use debug!() to log "A new Frog has been created" // 2. Use debug!() to log "A new Frog has been created"
debug!(target: "Frog::new", "A new Frog has been created");
Default::default() Default::default()
} }
pub fn hop(&mut self) { pub fn hop(&mut self) {
self.energy -= 1; self.energy -= 1;
// 3. Use info!() to log that a Frog hopped, and how much energy is left // 3. Use info!() to log that a Frog hopped, and how much energy is left
info!(target: "Frog::hop", "A frog hopped! It has {} energy left", self.energy);
if self.energy == 0 { if self.energy == 0 {
// 4. Use warn!() to warn that the frog will go to sleep since he ran out of energy // 4. Use warn!() to warn that the frog will go to sleep since he ran out of energy
warn!(target: "Frog::hop", "The frog will go to sleep since he ran out of energy");
self.sleep(); self.sleep();
} }
} }
pub fn sleep(&mut self) { pub fn sleep(&mut self) {
if self.sleeping { if self.sleeping {
// 5. Use error!() to log a (non-fatal) error stating that the Frog is already asleep // 5. Use error!() to log a (non-fatal) error stating that the Frog is already asleep
error!(target: "Frog::sleep", "The frog is already asleep");
} else { } else {
self.sleeping = true; self.sleeping = true;
} }
@@ -37,9 +43,12 @@ impl Frog {
impl Default for Frog { impl Default for Frog {
fn default() -> Self { fn default() -> Self {
// 6. Use trace!() to log that a default value was generated, with the debug representation // 6. Use trace!() to log that a default value was generated, with the debug representation
Frog { let frog = Frog {
energy: 5, energy: 5,
sleeping: false, sleeping: false,
} };
trace!(target: "Frog::Default", "A default Frog value was generated: {:?}", frog);
frog
} }
} }

View File

@@ -8,6 +8,7 @@ use frogger::Frog;
fn main() { fn main() {
// 8. Initialize env_logger using the init() function at the top level of the library // 8. Initialize env_logger using the init() function at the top level of the library
env_logger::init();
// 9. Run this program with `cargo run` and take a look at the default output. // 9. Run this program with `cargo run` and take a look at the default output.
// - Now run it again with an explicit log level, like `RUST_LOG=info cargo run` // - Now run it again with an explicit log level, like `RUST_LOG=info cargo run`

View File

@@ -9,15 +9,15 @@ edition = "2021"
# Challenge Help 1: If you choose to take on the challenge, you'll need to add `criterion` as a # Challenge Help 1: If you choose to take on the challenge, you'll need to add `criterion` as a
# development dependency. Here is one way to do it: # development dependency. Here is one way to do it:
# [dev-dependencies] [dev-dependencies]
# criterion = { version = "0.3", features = ["html_reports"] } criterion = { version = "0.3", features = ["html_reports"] }
# Challenge Help 2: Each benchmark needs a `[[bench]]` section with a name and disabling the harness. # Challenge Help 2: Each benchmark needs a `[[bench]]` section with a name and disabling the harness.
# A name "somename" will correspond with a file "benches/somename.rs" # A name "somename" will correspond with a file "benches/somename.rs"
# [[bench]] [[bench]]
# name = "somename" name = "somename"
# harness = false harness = false
# Challenge Help 3: The Criterion documentation has a great tutorial for how to actually write your # Challenge Help 3: The Criterion documentation has a great tutorial for how to actually write your
# benchmark. Don't skip the part about `black_box()`! # benchmark. Don't skip the part about `black_box()`!

View File

@@ -0,0 +1,11 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use testing::sploosh;
pub fn sploosh_benchmark(c: &mut Criterion) {
c.bench_function("sploosh", |b| {
b.iter(|| sploosh(black_box(8), black_box(9), black_box(10)))
});
}
criterion_group!(benches, sploosh_benchmark);
criterion_main!(benches);

View File

@@ -3,6 +3,7 @@ pub fn sploosh(x: i32, y: i32, z: i32) -> i32 {
(x, _, _) if x < 0 => 99, (x, _, _) if x < 0 => 99,
(1, 2, 3) => 4, (1, 2, 3) => 4,
(5, 6, 7) => 3, (5, 6, 7) => 3,
(8, 9, 10) => 7,
(x, y, z) => x + y - z, (x, y, z) => x + y - z,
} }
} }
@@ -13,9 +14,11 @@ pub fn splish(a: i32, b: i32) -> i32 {
// 1. Use the `cfg` attribute to mark the `test` module below as a test module // 1. Use the `cfg` attribute to mark the `test` module below as a test module
#[cfg(test)]
mod test { mod test {
// 2. Bring all the library items into scope with a `use` statement // 2. Bring all the library items into scope with a `use` statement
// Hint: It's okay to use `*` here. // Hint: It's okay to use `*` here.
use super::*;
// 3. Write a test function that verifies the following condition using the `assert_eq!` or // 3. Write a test function that verifies the following condition using the `assert_eq!` or
// `assert_ne!` macros // `assert_ne!` macros
@@ -26,10 +29,24 @@ mod test {
// `cargo test` should run your tests and pass // `cargo test` should run your tests and pass
// Hint: Don't forget the `#[test]` attribute for your test function! // Hint: Don't forget the `#[test]` attribute for your test function!
#[test]
fn test_sploosh() {
assert_eq!(sploosh(1, 2, 3), 4);
assert_ne!(sploosh(5, 6, 7), 4);
assert_eq!(sploosh(-1, 2, 3), 99);
}
// 4. Write a test function that verifies the following conditions using the `assert!` macro // 4. Write a test function that verifies the following conditions using the `assert!` macro
// - splish(100, 10) is negative // - splish(100, 10) is negative
// - splish(40, 20) is positive // - splish(40, 20) is positive
// - splish(9, 3) is 0 // - splish(9, 3) is 0
#[test]
fn test_splish() {
assert!(splish(100, 10) < 0);
assert!(splish(40, 20) > 0);
assert!(splish(9, 3) == 0);
}
} }
// 5. Create a `tests/` directory and an integration test file `tests/more_tests.rs` // 5. Create a `tests/` directory and an integration test file `tests/more_tests.rs`

View File

@@ -0,0 +1,6 @@
use testing::{splish, sploosh};
#[test]
pub fn test_sploosh_splish() {
assert_eq!(sploosh(splish(-1, 0), splish(1, 1), splish(3, 2)), 4);
}

View File

@@ -22,8 +22,8 @@ fn main() {
// join handle in a variable called `handle`. Once you've done this you should be able to run // join handle in a variable called `handle`. Once you've done this you should be able to run
// the code and see the output from the child thread's expensive sum in the middle of the main // the code and see the output from the child thread's expensive sum in the middle of the main
// thread's processing of letters. // thread's processing of letters.
//
//let handle = ... let handle = thread::spawn(|| expensive_sum(my_vector));
// While the child thread is running, the main thread will also do some work // While the child thread is running, the main thread will also do some work
for letter in vec!["a", "b", "c", "d", "e", "f"] { for letter in vec!["a", "b", "c", "d", "e", "f"] {
@@ -37,17 +37,16 @@ fn main() {
// to a variable named `result` // to a variable named `result`
// - Get the i32 out of `result` and store it in a `sum` variable. // - Get the i32 out of `result` and store it in a `sum` variable.
// let result = let result = handle.join();
// let sum = let sum = result.unwrap();
// println!("The child thread's expensive sum is {}", sum); println!("The child thread's expensive sum is {}", sum);
// 3. Time for some fun with channels! // 3. Time for some fun with channels!
// - Uncomment the block comment below (Find and remove the `/*` and `*/`). // - Uncomment the block comment below (Find and remove the `/*` and `*/`).
// - Create variables `tx` and `rx` and assign them to the sending and receiving ends of an // - Create variables `tx` and `rx` and assign them to the sending and receiving ends of an
// unbounded channel. Hint: An unbounded channel can be created with `channel::unbounded()` // unbounded channel. Hint: An unbounded channel can be created with `channel::unbounded()`
/* let (tx, rx) = channel::unbounded();
// let ...
// Cloning a channel makes another variable connected to that end of the channel so that you can // Cloning a channel makes another variable connected to that end of the channel so that you can
// send it to another thread. We want another variable that can be used for sending... // send it to another thread. We want another variable that can be used for sending...
@@ -62,7 +61,7 @@ fn main() {
// Thread A // Thread A
let handle_a = thread::spawn(move || { let handle_a = thread::spawn(move || {
sleep_ms(0); sleep_ms(500);
tx2.send("Thread A: 1").unwrap(); tx2.send("Thread A: 1").unwrap();
sleep_ms(200); sleep_ms(200);
tx2.send("Thread A: 2").unwrap(); tx2.send("Thread A: 2").unwrap();
@@ -88,12 +87,40 @@ fn main() {
// 5. Oops, we forgot to join "Thread A" and "Thread B". That's bad hygiene! // 5. Oops, we forgot to join "Thread A" and "Thread B". That's bad hygiene!
// - Use the thread handles to join both threads without getting any compiler warnings. // - Use the thread handles to join both threads without getting any compiler warnings.
*/ let _ = handle_a.join();
let _ = handle_b.join();
// Challenge: Make two child threads and give them each a receiving end to a channel. From the // Challenge: Make two child threads and give them each a receiving end to a channel. From the
// main thread loop through several values and print each out and then send it to the channel. // main thread loop through several values and print each out and then send it to the channel.
// On the child threads print out the values you receive. Close the sending side in the main // On the child threads print out the values you receive. Close the sending side in the main
// thread by calling `drop(tx)` (assuming you named your sender channel variable `tx`). Join // thread by calling `drop(tx)` (assuming you named your sender channel variable `tx`). Join
// the child threads. // the child threads.
let (tx, rx) = channel::unbounded();
let rx2 = rx.clone();
let thread_a_handle = thread::spawn(move || {
for n in rx {
println!("Thread A received: {}", n);
sleep_ms(10);
}
});
let thread_b_handle = thread::spawn(move || {
for n in rx2 {
println!("Thread B received: {}", n);
sleep_ms(10);
}
});
for number in vec![1, 2, 3, 4, 5] {
println!("NUMBER: {}", number);
let _ = tx.send(number);
}
drop(tx);
let _ = thread_a_handle.join();
let _ = thread_b_handle.join();
println!("Main thread: Exiting.") println!("Main thread: Exiting.")
} }

View File

@@ -1,15 +1,39 @@
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Cake { pub enum Cake {
Chocolate, Chocolate,
MapleBacon, MapleBacon,
Spice, Spice,
} }
#[derive(Debug)]
pub struct Party { pub struct Party {
pub at_restaurant: bool, pub at_restaurant: bool,
pub num_people: u8, pub num_people: u8,
pub cake: Cake, pub cake: Cake,
} }
impl Default for Party {
fn default() -> Self {
Self {
at_restaurant: true,
num_people: 8,
cake: Cake::Chocolate,
}
}
}
impl PartialEq for Party {
fn eq(&self, other: &Self) -> bool {
self.cake == other.cake
}
}
impl From<&Party> for Cake {
fn from(party: &Party) -> Self {
party.cake
}
}
fn main() { fn main() {
// 1. The code below doesn't work because Cake doesn't implement Debug. // 1. The code below doesn't work because Cake doesn't implement Debug.
// - Derive the Debug trait for the Cake enum above so this code will work. Then, run the code. // - Derive the Debug trait for the Cake enum above so this code will work. Then, run the code.
@@ -23,11 +47,11 @@ fn main() {
// function instead of moved. // function instead of moved.
// - Hint: You may need to derive another trait in order to be able to derive the Copy trait // - Hint: You may need to derive another trait in order to be able to derive the Copy trait
// match cake { match cake {
// Cake::Chocolate => println!("The name's Chocolate. Dark...Chocolate."), Cake::Chocolate => println!("The name's Chocolate. Dark...Chocolate."),
// Cake::MapleBacon => println!("Dreams do come true!"), Cake::MapleBacon => println!("Dreams do come true!"),
// Cake::Spice => println!("Great, let's spice it up!"), Cake::Spice => println!("Great, let's spice it up!"),
// } }
// 3. Uncomment the println below. It doesn't work since the Party struct doesn't implement the // 3. Uncomment the println below. It doesn't work since the Party struct doesn't implement the
// Debug or Default traits. // Debug or Default traits.
@@ -44,7 +68,7 @@ fn main() {
// Hint: If you get stuck, there is an example at // Hint: If you get stuck, there is an example at
// https://doc.rust-lang.org/std/default/trait.Default.html#how-can-i-implement-default // https://doc.rust-lang.org/std/default/trait.Default.html#how-can-i-implement-default
// println!("The default Party is\n{:#?}", Party::default()); println!("The default Party is\n{:#?}", Party::default());
// 4. You prefer Maple Bacon cake. Use "struct update syntax" to create a Party with `cake` // 4. You prefer Maple Bacon cake. Use "struct update syntax" to create a Party with `cake`
// set to `Cake::MapleBacon`, but the rest of the values are default. // set to `Cake::MapleBacon`, but the rest of the values are default.
@@ -52,10 +76,11 @@ fn main() {
// Hint: The trick to struct update syntax is specifying the value(s) you want to customize // Hint: The trick to struct update syntax is specifying the value(s) you want to customize
// first and then ending the struct with `..Default::default()` -- but no comma after that! // first and then ending the struct with `..Default::default()` -- but no comma after that!
// let party = Party { let party = Party {
// ... cake: Cake::MapleBacon,
// }; ..Default::default()
// println!("Yes! My party has my favorite {:?} cake!", party.cake); };
println!("Yes! My party has my favorite {:?} cake!", party.cake);
// 5. Parties are "equal" if they have the same cake. // 5. Parties are "equal" if they have the same cake.
// - Derive the PartialEq trait for the Cake enum so Cakes can be compared. // - Derive the PartialEq trait for the Cake enum so Cakes can be compared.
@@ -63,14 +88,15 @@ fn main() {
// then they are equal, no matter the location or number of attendees at the party. // then they are equal, no matter the location or number of attendees at the party.
// - Uncomment and run the code below. // - Uncomment and run the code below.
// let other_party = Party { let other_party = Party {
// at_restaurant: false, at_restaurant: false,
// num_people: 235, num_people: 235,
// cake: Cake::MapleBacon, cake: Cake::MapleBacon,
// }; };
// if party == other_party {
// println!("Your party is just like mine!"); if party == other_party {
// } println!("Your party is just like mine!");
}
// Challenge: You would like to be able to pass a Party struct into the smell_cake() function // Challenge: You would like to be able to pass a Party struct into the smell_cake() function
// which takes a type T which implements the Into<Cake> trait. // which takes a type T which implements the Into<Cake> trait.
@@ -78,20 +104,22 @@ fn main() {
// - Implement `From<Party> for Cake` so that the function call below works. // - Implement `From<Party> for Cake` so that the function call below works.
// //
// smell_cake(party); smell_cake(&party);
// Challenge 2: Implement `From<&Party> for Cake` so that you can smell your cake without // Challenge 2: Implement `From<&Party> for Cake` so that you can smell your cake without
// consuming it. Change the code above to pass in a &party. Then uncomment and run the code // consuming it. Change the code above to pass in a &party. Then uncomment and run the code
// below. After all, you want to smell your cake and eat it, too! // below. After all, you want to smell your cake and eat it, too!
// println!("Yum! I'm eating this cake: {:?}. Oops, I dropped it on the floor.", party.cake); println!(
// drop(cake); "Yum! I'm eating this cake: {:?}. Oops, I dropped it on the floor.",
party.cake
);
} }
pub fn admire_cake(cake: Cake) { pub fn admire_cake(cake: Cake) {
println!("What a nice {:?} cake! 🎂", cake); println!("What a nice {:?} cake! 🎂", cake);
} }
// pub fn smell_cake<T: Into<Cake>>(something: T) { pub fn smell_cake<T: Into<Cake>>(something: T) {
// println!("Hmm...something smells like a {:?} cake!", something.into()); println!("Hmm...something smells like a {:?} cake!", something.into());
// } }