First commit
This commit is contained in:
5
solutions/00_intro/intro1.rs
Normal file
5
solutions/00_intro/intro1.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
fn main() {
|
||||
// Congratulations, you finished the first exercise 🎉
|
||||
// As an introduction to Rustlings, the first exercise only required
|
||||
// entering `n` in the terminal to go to the next exercise.
|
||||
}
|
||||
4
solutions/00_intro/intro2.rs
Normal file
4
solutions/00_intro/intro2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// `println!` instead of `printline!`.
|
||||
println!("Hello world!");
|
||||
}
|
||||
6
solutions/01_variables/variables1.rs
Normal file
6
solutions/01_variables/variables1.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
// Declaring variables requires the `let` keyword.
|
||||
let x = 5;
|
||||
|
||||
println!("x has the value {x}");
|
||||
}
|
||||
16
solutions/01_variables/variables2.rs
Normal file
16
solutions/01_variables/variables2.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
fn main() {
|
||||
// The easiest way to fix the compiler error is to initialize the
|
||||
// variable `x`. By setting its value to an integer, Rust infers its type
|
||||
// as `i32` which is the default type for integers.
|
||||
let x = 42;
|
||||
|
||||
// But we can enforce a type different from the default `i32` by adding
|
||||
// a type annotation:
|
||||
// let x: u8 = 42;
|
||||
|
||||
if x == 10 {
|
||||
println!("x is ten!");
|
||||
} else {
|
||||
println!("x is not ten!");
|
||||
}
|
||||
}
|
||||
15
solutions/01_variables/variables3.rs
Normal file
15
solutions/01_variables/variables3.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
#![allow(clippy::needless_late_init)]
|
||||
|
||||
fn main() {
|
||||
// Reading uninitialized variables isn't allowed in Rust!
|
||||
// Therefore, we need to assign a value first.
|
||||
let x: i32 = 42;
|
||||
|
||||
println!("Number {x}");
|
||||
|
||||
// It is possible to declare a variable and initialize it later.
|
||||
// But it can't be used before initialization.
|
||||
let y: i32;
|
||||
y = 42;
|
||||
println!("Number {y}");
|
||||
}
|
||||
9
solutions/01_variables/variables4.rs
Normal file
9
solutions/01_variables/variables4.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
fn main() {
|
||||
// In Rust, variables are immutable by default.
|
||||
// Adding the `mut` keyword after `let` makes the declared variable mutable.
|
||||
let mut x = 3;
|
||||
println!("Number {x}");
|
||||
|
||||
x = 5;
|
||||
println!("Number {x}");
|
||||
}
|
||||
9
solutions/01_variables/variables5.rs
Normal file
9
solutions/01_variables/variables5.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
fn main() {
|
||||
let number = "T-H-R-E-E";
|
||||
println!("Spell a number: {number}");
|
||||
|
||||
// Using variable shadowing
|
||||
// https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
|
||||
let number = 3;
|
||||
println!("Number plus two is: {}", number + 2);
|
||||
}
|
||||
6
solutions/01_variables/variables6.rs
Normal file
6
solutions/01_variables/variables6.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
// The type of constants must always be annotated.
|
||||
const NUMBER: u64 = 3;
|
||||
|
||||
fn main() {
|
||||
println!("Number: {NUMBER}");
|
||||
}
|
||||
8
solutions/02_functions/functions1.rs
Normal file
8
solutions/02_functions/functions1.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
// Some function with the name `call_me` without arguments or a return value.
|
||||
fn call_me() {
|
||||
println!("Hello world!");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
call_me();
|
||||
}
|
||||
11
solutions/02_functions/functions2.rs
Normal file
11
solutions/02_functions/functions2.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
// The type of function arguments must be annotated.
|
||||
// Added the type annotation `u64`.
|
||||
fn call_me(num: u64) {
|
||||
for i in 0..num {
|
||||
println!("Ring! Call number {}", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
call_me(3);
|
||||
}
|
||||
10
solutions/02_functions/functions3.rs
Normal file
10
solutions/02_functions/functions3.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
fn call_me(num: u8) {
|
||||
for i in 0..num {
|
||||
println!("Ring! Call number {}", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// `call_me` expects an argument.
|
||||
call_me(5);
|
||||
}
|
||||
17
solutions/02_functions/functions4.rs
Normal file
17
solutions/02_functions/functions4.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
fn is_even(num: i64) -> bool {
|
||||
num % 2 == 0
|
||||
}
|
||||
|
||||
// The return type must always be annotated.
|
||||
fn sale_price(price: i64) -> i64 {
|
||||
if is_even(price) {
|
||||
price - 10
|
||||
} else {
|
||||
price - 3
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let original_price = 51;
|
||||
println!("Your sale price is {}", sale_price(original_price));
|
||||
}
|
||||
9
solutions/02_functions/functions5.rs
Normal file
9
solutions/02_functions/functions5.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
fn square(num: i32) -> i32 {
|
||||
// Removed the semicolon `;` at the end of the line below to implicitly return the result.
|
||||
num * num
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let answer = square(3);
|
||||
println!("The square of 3 is {answer}");
|
||||
}
|
||||
28
solutions/03_if/if1.rs
Normal file
28
solutions/03_if/if1.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
fn bigger(a: i32, b: i32) -> i32 {
|
||||
if a > b { a } else { b }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
// Don't mind this for now :)
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn ten_is_bigger_than_eight() {
|
||||
assert_eq!(10, bigger(10, 8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fortytwo_is_bigger_than_thirtytwo() {
|
||||
assert_eq!(42, bigger(32, 42));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn equal_numbers() {
|
||||
assert_eq!(42, bigger(42, 42));
|
||||
}
|
||||
}
|
||||
35
solutions/03_if/if2.rs
Normal file
35
solutions/03_if/if2.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
fn picky_eater(food: &str) -> &str {
|
||||
if food == "strawberry" {
|
||||
"Yummy!"
|
||||
} else if food == "potato" {
|
||||
"I guess I can eat that."
|
||||
} else {
|
||||
"No thanks!"
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn yummy_food() {
|
||||
assert_eq!(picky_eater("strawberry"), "Yummy!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn neutral_food() {
|
||||
assert_eq!(picky_eater("potato"), "I guess I can eat that.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_disliked_food() {
|
||||
assert_eq!(picky_eater("broccoli"), "No thanks!");
|
||||
assert_eq!(picky_eater("gummy bears"), "No thanks!");
|
||||
assert_eq!(picky_eater("literally anything"), "No thanks!");
|
||||
}
|
||||
}
|
||||
53
solutions/03_if/if3.rs
Normal file
53
solutions/03_if/if3.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
fn animal_habitat(animal: &str) -> &str {
|
||||
let identifier = if animal == "crab" {
|
||||
1
|
||||
} else if animal == "gopher" {
|
||||
2
|
||||
} else if animal == "snake" {
|
||||
3
|
||||
} else {
|
||||
// Any unused identifier.
|
||||
4
|
||||
};
|
||||
|
||||
// Instead of such an identifier, you would use an enum in Rust.
|
||||
// But we didn't get into enums yet.
|
||||
if identifier == 1 {
|
||||
"Beach"
|
||||
} else if identifier == 2 {
|
||||
"Burrow"
|
||||
} else if identifier == 3 {
|
||||
"Desert"
|
||||
} else {
|
||||
"Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn gopher_lives_in_burrow() {
|
||||
assert_eq!(animal_habitat("gopher"), "Burrow")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn snake_lives_in_desert() {
|
||||
assert_eq!(animal_habitat("snake"), "Desert")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crab_lives_on_beach() {
|
||||
assert_eq!(animal_habitat("crab"), "Beach")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unknown_animal() {
|
||||
assert_eq!(animal_habitat("dinosaur"), "Unknown")
|
||||
}
|
||||
}
|
||||
11
solutions/04_primitive_types/primitive_types1.rs
Normal file
11
solutions/04_primitive_types/primitive_types1.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
let is_morning = true;
|
||||
if is_morning {
|
||||
println!("Good morning!");
|
||||
}
|
||||
|
||||
let is_evening = !is_morning;
|
||||
if is_evening {
|
||||
println!("Good evening!");
|
||||
}
|
||||
}
|
||||
21
solutions/04_primitive_types/primitive_types2.rs
Normal file
21
solutions/04_primitive_types/primitive_types2.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
fn main() {
|
||||
let my_first_initial = 'C';
|
||||
if my_first_initial.is_alphabetic() {
|
||||
println!("Alphabetical!");
|
||||
} else if my_first_initial.is_numeric() {
|
||||
println!("Numerical!");
|
||||
} else {
|
||||
println!("Neither alphabetic nor numeric!");
|
||||
}
|
||||
|
||||
// Example with an emoji.
|
||||
let your_character = '🦀';
|
||||
|
||||
if your_character.is_alphabetic() {
|
||||
println!("Alphabetical!");
|
||||
} else if your_character.is_numeric() {
|
||||
println!("Numerical!");
|
||||
} else {
|
||||
println!("Neither alphabetic nor numeric!");
|
||||
}
|
||||
}
|
||||
11
solutions/04_primitive_types/primitive_types3.rs
Normal file
11
solutions/04_primitive_types/primitive_types3.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
// An array with 100 elements of the value 42.
|
||||
let a = [42; 100];
|
||||
|
||||
if a.len() >= 100 {
|
||||
println!("Wow, that's a big array!");
|
||||
} else {
|
||||
println!("Meh, I eat arrays like that for breakfast.");
|
||||
panic!("Array not big enough, more elements needed");
|
||||
}
|
||||
}
|
||||
23
solutions/04_primitive_types/primitive_types4.rs
Normal file
23
solutions/04_primitive_types/primitive_types4.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn slice_out_of_array() {
|
||||
let a = [1, 2, 3, 4, 5];
|
||||
// 0 1 2 3 4 <- indices
|
||||
// -------
|
||||
// |
|
||||
// +--- slice
|
||||
|
||||
// Note that the upper index 4 is excluded.
|
||||
let nice_slice = &a[1..4];
|
||||
assert_eq!([2, 3, 4], nice_slice);
|
||||
|
||||
// The upper index can be included by using the syntax `..=` (with `=` sign)
|
||||
let nice_slice = &a[1..=3];
|
||||
assert_eq!([2, 3, 4], nice_slice);
|
||||
}
|
||||
}
|
||||
8
solutions/04_primitive_types/primitive_types5.rs
Normal file
8
solutions/04_primitive_types/primitive_types5.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
fn main() {
|
||||
let cat = ("Furry McFurson", 3.5);
|
||||
|
||||
// Destructuring the tuple.
|
||||
let (name, age) = cat;
|
||||
|
||||
println!("{name} is {age} years old");
|
||||
}
|
||||
16
solutions/04_primitive_types/primitive_types6.rs
Normal file
16
solutions/04_primitive_types/primitive_types6.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn indexing_tuple() {
|
||||
let numbers = (1, 2, 3);
|
||||
|
||||
// Tuple indexing syntax.
|
||||
let second = numbers.1;
|
||||
|
||||
assert_eq!(second, 2, "This is not the 2nd number in the tuple!");
|
||||
}
|
||||
}
|
||||
23
solutions/05_vecs/vecs1.rs
Normal file
23
solutions/05_vecs/vecs1.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
|
||||
let a = [10, 20, 30, 40]; // Array
|
||||
|
||||
// Used the `vec!` macro.
|
||||
let v = vec![10, 20, 30, 40];
|
||||
|
||||
(a, v)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_array_and_vec_similarity() {
|
||||
let (a, v) = array_and_vec();
|
||||
assert_eq!(a, *v);
|
||||
}
|
||||
}
|
||||
55
solutions/05_vecs/vecs2.rs
Normal file
55
solutions/05_vecs/vecs2.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
fn vec_loop(input: &[i32]) -> Vec<i32> {
|
||||
let mut output = Vec::new();
|
||||
|
||||
for element in input {
|
||||
output.push(2 * element);
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
fn vec_map_example(input: &[i32]) -> Vec<i32> {
|
||||
// An example of collecting a vector after mapping.
|
||||
// We map each element of the `input` slice to its value plus 1.
|
||||
// If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
|
||||
input.iter().map(|element| element + 1).collect()
|
||||
}
|
||||
|
||||
fn vec_map(input: &[i32]) -> Vec<i32> {
|
||||
// We will dive deeper into iterators, but for now, this is all what you
|
||||
// had to do!
|
||||
// Advanced note: This method is more efficient because it automatically
|
||||
// preallocates enough capacity. This can be done manually in `vec_loop`
|
||||
// using `Vec::with_capacity(input.len())` instead of `Vec::new()`.
|
||||
input.iter().map(|element| 2 * element).collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_vec_loop() {
|
||||
let input = [2, 4, 6, 8, 10];
|
||||
let ans = vec_loop(&input);
|
||||
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_map_example() {
|
||||
let input = [1, 2, 3];
|
||||
let ans = vec_map_example(&input);
|
||||
assert_eq!(ans, [2, 3, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_map() {
|
||||
let input = [2, 4, 6, 8, 10];
|
||||
let ans = vec_map(&input);
|
||||
assert_eq!(ans, [4, 8, 12, 16, 20]);
|
||||
}
|
||||
}
|
||||
25
solutions/06_move_semantics/move_semantics1.rs
Normal file
25
solutions/06_move_semantics/move_semantics1.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||
let mut vec = vec;
|
||||
// ^^^ added
|
||||
|
||||
vec.push(88);
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn move_semantics1() {
|
||||
let vec0 = vec![22, 44, 66];
|
||||
let vec1 = fill_vec(vec0);
|
||||
// `vec0` can't be accessed anymore because it is moved to `fill_vec`.
|
||||
assert_eq!(vec1, vec![22, 44, 66, 88]);
|
||||
}
|
||||
}
|
||||
28
solutions/06_move_semantics/move_semantics2.rs
Normal file
28
solutions/06_move_semantics/move_semantics2.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
||||
let mut vec = vec;
|
||||
|
||||
vec.push(88);
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn move_semantics2() {
|
||||
let vec0 = vec![22, 44, 66];
|
||||
|
||||
// Cloning `vec0` so that the clone is moved into `fill_vec`, not `vec0`
|
||||
// itself.
|
||||
let vec1 = fill_vec(vec0.clone());
|
||||
|
||||
assert_eq!(vec0, [22, 44, 66]);
|
||||
assert_eq!(vec1, [22, 44, 66, 88]);
|
||||
}
|
||||
}
|
||||
22
solutions/06_move_semantics/move_semantics3.rs
Normal file
22
solutions/06_move_semantics/move_semantics3.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
|
||||
// ^^^ added
|
||||
vec.push(88);
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn move_semantics3() {
|
||||
let vec0 = vec![22, 44, 66];
|
||||
let vec1 = fill_vec(vec0);
|
||||
assert_eq!(vec1, [22, 44, 66, 88]);
|
||||
}
|
||||
}
|
||||
19
solutions/06_move_semantics/move_semantics4.rs
Normal file
19
solutions/06_move_semantics/move_semantics4.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn move_semantics4() {
|
||||
let mut x = Vec::new();
|
||||
let y = &mut x;
|
||||
// `y` used here.
|
||||
y.push(42);
|
||||
// The mutable reference `y` is not used anymore,
|
||||
// therefore a new reference can be created.
|
||||
let z = &mut x;
|
||||
z.push(13);
|
||||
assert_eq!(x, [42, 13]);
|
||||
}
|
||||
}
|
||||
23
solutions/06_move_semantics/move_semantics5.rs
Normal file
23
solutions/06_move_semantics/move_semantics5.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
#![allow(clippy::ptr_arg)]
|
||||
|
||||
// Borrows instead of taking ownership.
|
||||
// It is recommended to use `&str` instead of `&String` here. But this is
|
||||
// enough for now because we didn't handle strings yet.
|
||||
fn get_char(data: &String) -> char {
|
||||
data.chars().last().unwrap()
|
||||
}
|
||||
|
||||
// Takes ownership instead of borrowing.
|
||||
fn string_uppercase(mut data: String) {
|
||||
data = data.to_uppercase();
|
||||
|
||||
println!("{data}");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let data = "Rust is great!".to_string();
|
||||
|
||||
get_char(&data);
|
||||
|
||||
string_uppercase(data);
|
||||
}
|
||||
49
solutions/07_structs/structs1.rs
Normal file
49
solutions/07_structs/structs1.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
struct ColorRegularStruct {
|
||||
red: u8,
|
||||
green: u8,
|
||||
blue: u8,
|
||||
}
|
||||
|
||||
struct ColorTupleStruct(u8, u8, u8);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct UnitStruct;
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn regular_structs() {
|
||||
let green = ColorRegularStruct {
|
||||
red: 0,
|
||||
green: 255,
|
||||
blue: 0,
|
||||
};
|
||||
|
||||
assert_eq!(green.red, 0);
|
||||
assert_eq!(green.green, 255);
|
||||
assert_eq!(green.blue, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_structs() {
|
||||
let green = ColorTupleStruct(0, 255, 0);
|
||||
|
||||
assert_eq!(green.0, 0);
|
||||
assert_eq!(green.1, 255);
|
||||
assert_eq!(green.2, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_structs() {
|
||||
let unit_struct = UnitStruct;
|
||||
let message = format!("{unit_struct:?}s are fun!");
|
||||
|
||||
assert_eq!(message, "UnitStructs are fun!");
|
||||
}
|
||||
}
|
||||
51
solutions/07_structs/structs2.rs
Normal file
51
solutions/07_structs/structs2.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
#[derive(Debug)]
|
||||
struct Order {
|
||||
name: String,
|
||||
year: u32,
|
||||
made_by_phone: bool,
|
||||
made_by_mobile: bool,
|
||||
made_by_email: bool,
|
||||
item_number: u32,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
fn create_order_template() -> Order {
|
||||
Order {
|
||||
name: String::from("Bob"),
|
||||
year: 2019,
|
||||
made_by_phone: false,
|
||||
made_by_mobile: false,
|
||||
made_by_email: true,
|
||||
item_number: 123,
|
||||
count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn your_order() {
|
||||
let order_template = create_order_template();
|
||||
|
||||
let your_order = Order {
|
||||
name: String::from("Hacker in Rust"),
|
||||
count: 1,
|
||||
// Struct update syntax
|
||||
..order_template
|
||||
};
|
||||
|
||||
assert_eq!(your_order.name, "Hacker in Rust");
|
||||
assert_eq!(your_order.year, order_template.year);
|
||||
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
|
||||
assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
|
||||
assert_eq!(your_order.made_by_email, order_template.made_by_email);
|
||||
assert_eq!(your_order.item_number, order_template.item_number);
|
||||
assert_eq!(your_order.count, 1);
|
||||
}
|
||||
}
|
||||
83
solutions/07_structs/structs3.rs
Normal file
83
solutions/07_structs/structs3.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
#[derive(Debug)]
|
||||
struct Package {
|
||||
sender_country: String,
|
||||
recipient_country: String,
|
||||
weight_in_grams: u32,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
fn new(sender_country: String, recipient_country: String, weight_in_grams: u32) -> Self {
|
||||
if weight_in_grams < 10 {
|
||||
// This isn't how you should handle errors in Rust, but we will
|
||||
// learn about error handling later.
|
||||
panic!("Can't ship a package with weight below 10 grams");
|
||||
}
|
||||
|
||||
Self {
|
||||
sender_country,
|
||||
recipient_country,
|
||||
weight_in_grams,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_international(&self) -> bool {
|
||||
// ^^^^^^^ added
|
||||
self.sender_country != self.recipient_country
|
||||
}
|
||||
|
||||
fn get_fees(&self, cents_per_gram: u32) -> u32 {
|
||||
// ^^^^^^ added
|
||||
self.weight_in_grams * cents_per_gram
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn fail_creating_weightless_package() {
|
||||
let sender_country = String::from("Spain");
|
||||
let recipient_country = String::from("Austria");
|
||||
|
||||
Package::new(sender_country, recipient_country, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_international_package() {
|
||||
let sender_country = String::from("Spain");
|
||||
let recipient_country = String::from("Russia");
|
||||
|
||||
let package = Package::new(sender_country, recipient_country, 1200);
|
||||
|
||||
assert!(package.is_international());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_local_package() {
|
||||
let sender_country = String::from("Canada");
|
||||
let recipient_country = sender_country.clone();
|
||||
|
||||
let package = Package::new(sender_country, recipient_country, 1200);
|
||||
|
||||
assert!(!package.is_international());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calculate_transport_fees() {
|
||||
let sender_country = String::from("Spain");
|
||||
let recipient_country = String::from("Spain");
|
||||
|
||||
let cents_per_gram = 3;
|
||||
|
||||
let package = Package::new(sender_country, recipient_country, 1500);
|
||||
|
||||
assert_eq!(package.get_fees(cents_per_gram), 4500);
|
||||
assert_eq!(package.get_fees(cents_per_gram * 2), 9000);
|
||||
}
|
||||
}
|
||||
16
solutions/08_enums/enums1.rs
Normal file
16
solutions/08_enums/enums1.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
#[derive(Debug)]
|
||||
enum Message {
|
||||
Resize,
|
||||
Move,
|
||||
Echo,
|
||||
ChangeColor,
|
||||
Quit,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", Message::Resize);
|
||||
println!("{:?}", Message::Move);
|
||||
println!("{:?}", Message::Echo);
|
||||
println!("{:?}", Message::ChangeColor);
|
||||
println!("{:?}", Message::Quit);
|
||||
}
|
||||
37
solutions/08_enums/enums2.rs
Normal file
37
solutions/08_enums/enums2.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: u64,
|
||||
y: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Message {
|
||||
Resize { width: u64, height: u64 },
|
||||
Move(Point),
|
||||
Echo(String),
|
||||
ChangeColor(u8, u8, u8),
|
||||
Quit,
|
||||
}
|
||||
|
||||
impl Message {
|
||||
fn call(&self) {
|
||||
println!("{self:?}");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let messages = [
|
||||
Message::Resize {
|
||||
width: 10,
|
||||
height: 30,
|
||||
},
|
||||
Message::Move(Point { x: 10, y: 15 }),
|
||||
Message::Echo(String::from("hello world")),
|
||||
Message::ChangeColor(200, 255, 255),
|
||||
Message::Quit,
|
||||
];
|
||||
|
||||
for message in &messages {
|
||||
message.call();
|
||||
}
|
||||
}
|
||||
92
solutions/08_enums/enums3.rs
Normal file
92
solutions/08_enums/enums3.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
struct Point {
|
||||
x: u64,
|
||||
y: u64,
|
||||
}
|
||||
|
||||
enum Message {
|
||||
Resize { width: u64, height: u64 },
|
||||
Move(Point),
|
||||
Echo(String),
|
||||
ChangeColor(u8, u8, u8),
|
||||
Quit,
|
||||
}
|
||||
|
||||
struct State {
|
||||
width: u64,
|
||||
height: u64,
|
||||
position: Point,
|
||||
message: String,
|
||||
color: (u8, u8, u8),
|
||||
quit: bool,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn resize(&mut self, width: u64, height: u64) {
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
}
|
||||
|
||||
fn move_position(&mut self, point: Point) {
|
||||
self.position = point;
|
||||
}
|
||||
|
||||
fn echo(&mut self, s: String) {
|
||||
self.message = s;
|
||||
}
|
||||
|
||||
fn change_color(&mut self, red: u8, green: u8, blue: u8) {
|
||||
self.color = (red, green, blue);
|
||||
}
|
||||
|
||||
fn quit(&mut self) {
|
||||
self.quit = true;
|
||||
}
|
||||
|
||||
fn process(&mut self, message: Message) {
|
||||
match message {
|
||||
Message::Resize { width, height } => self.resize(width, height),
|
||||
Message::Move(point) => self.move_position(point),
|
||||
Message::Echo(string) => self.echo(string),
|
||||
Message::ChangeColor(red, green, blue) => self.change_color(red, green, blue),
|
||||
Message::Quit => self.quit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_match_message_call() {
|
||||
let mut state = State {
|
||||
width: 0,
|
||||
height: 0,
|
||||
position: Point { x: 0, y: 0 },
|
||||
message: String::from("hello world"),
|
||||
color: (0, 0, 0),
|
||||
quit: false,
|
||||
};
|
||||
|
||||
state.process(Message::Resize {
|
||||
width: 10,
|
||||
height: 30,
|
||||
});
|
||||
state.process(Message::Move(Point { x: 10, y: 15 }));
|
||||
state.process(Message::Echo(String::from("Hello world!")));
|
||||
state.process(Message::ChangeColor(255, 0, 255));
|
||||
state.process(Message::Quit);
|
||||
|
||||
assert_eq!(state.width, 10);
|
||||
assert_eq!(state.height, 30);
|
||||
assert_eq!(state.position.x, 10);
|
||||
assert_eq!(state.position.y, 15);
|
||||
assert_eq!(state.message, "Hello world!");
|
||||
assert_eq!(state.color, (255, 0, 255));
|
||||
assert!(state.quit);
|
||||
}
|
||||
}
|
||||
9
solutions/09_strings/strings1.rs
Normal file
9
solutions/09_strings/strings1.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
fn current_favorite_color() -> String {
|
||||
// Equivalent to `String::from("blue")`
|
||||
"blue".to_string()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let answer = current_favorite_color();
|
||||
println!("My current favorite color is {answer}");
|
||||
}
|
||||
15
solutions/09_strings/strings2.rs
Normal file
15
solutions/09_strings/strings2.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
fn is_a_color_word(attempt: &str) -> bool {
|
||||
attempt == "green" || attempt == "blue" || attempt == "red"
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let word = String::from("green");
|
||||
|
||||
if is_a_color_word(&word) {
|
||||
// ^ added to have `&String` which is automatically
|
||||
// coerced to `&str` by the compiler.
|
||||
println!("That is a color word I know!");
|
||||
} else {
|
||||
println!("That is not a color word I know.");
|
||||
}
|
||||
}
|
||||
49
solutions/09_strings/strings3.rs
Normal file
49
solutions/09_strings/strings3.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
fn trim_me(input: &str) -> &str {
|
||||
input.trim()
|
||||
}
|
||||
|
||||
fn compose_me(input: &str) -> String {
|
||||
// The macro `format!` has the same syntax as `println!`, but it returns a
|
||||
// string instead of printing it to the terminal.
|
||||
// Equivalent to `input.to_string() + " world!"`
|
||||
format!("{input} world!")
|
||||
}
|
||||
|
||||
fn replace_me(input: &str) -> String {
|
||||
input.replace("cars", "balloons")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn trim_a_string() {
|
||||
assert_eq!(trim_me("Hello! "), "Hello!");
|
||||
assert_eq!(trim_me(" What's up!"), "What's up!");
|
||||
assert_eq!(trim_me(" Hola! "), "Hola!");
|
||||
assert_eq!(trim_me("Hi!"), "Hi!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compose_a_string() {
|
||||
assert_eq!(compose_me("Hello"), "Hello world!");
|
||||
assert_eq!(compose_me("Goodbye"), "Goodbye world!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replace_a_string() {
|
||||
assert_eq!(
|
||||
replace_me("I think cars are cool"),
|
||||
"I think balloons are cool",
|
||||
);
|
||||
assert_eq!(
|
||||
replace_me("I love to look at cars"),
|
||||
"I love to look at balloons",
|
||||
);
|
||||
}
|
||||
}
|
||||
38
solutions/09_strings/strings4.rs
Normal file
38
solutions/09_strings/strings4.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
fn string_slice(arg: &str) {
|
||||
println!("{arg}");
|
||||
}
|
||||
|
||||
fn string(arg: String) {
|
||||
println!("{arg}");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
string_slice("blue");
|
||||
|
||||
string("red".to_string());
|
||||
|
||||
string(String::from("hi"));
|
||||
|
||||
string("rust is fun!".to_owned());
|
||||
|
||||
// Here, both answers work.
|
||||
// `.into()` converts a type into an expected type.
|
||||
// If it is called where `String` is expected, it will convert `&str` to `String`.
|
||||
string("nice weather".into());
|
||||
// But if it is called where `&str` is expected, then `&str` is kept `&str` since no conversion is needed.
|
||||
// If you remove the `#[allow(…)]` line, then Clippy will tell you to remove `.into()` below since it is a useless conversion.
|
||||
#[allow(clippy::useless_conversion)]
|
||||
string_slice("nice weather".into());
|
||||
|
||||
string(format!("Interpolation {}", "Station"));
|
||||
|
||||
// WARNING: This is byte indexing, not character indexing.
|
||||
// Character indexing can be done using `s.chars().nth(INDEX)`.
|
||||
string_slice(&String::from("abc")[0..1]);
|
||||
|
||||
string_slice(" hello there ".trim());
|
||||
|
||||
string("Happy Monday!".replace("Mon", "Tues"));
|
||||
|
||||
string("mY sHiFt KeY iS sTiCkY".to_lowercase());
|
||||
}
|
||||
15
solutions/10_modules/modules1.rs
Normal file
15
solutions/10_modules/modules1.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
mod sausage_factory {
|
||||
fn get_secret_recipe() -> String {
|
||||
String::from("Ginger")
|
||||
}
|
||||
|
||||
// Added `pub` before `fn` to make the function accessible outside the module.
|
||||
pub fn make_sausage() {
|
||||
get_secret_recipe();
|
||||
println!("sausage!");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sausage_factory::make_sausage();
|
||||
}
|
||||
23
solutions/10_modules/modules2.rs
Normal file
23
solutions/10_modules/modules2.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
mod delicious_snacks {
|
||||
// Added `pub` and used the expected alias after `as`.
|
||||
pub use self::fruits::PEAR as fruit;
|
||||
pub use self::veggies::CUCUMBER as veggie;
|
||||
|
||||
mod fruits {
|
||||
pub const PEAR: &str = "Pear";
|
||||
pub const APPLE: &str = "Apple";
|
||||
}
|
||||
|
||||
mod veggies {
|
||||
pub const CUCUMBER: &str = "Cucumber";
|
||||
pub const CARROT: &str = "Carrot";
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!(
|
||||
"favorite snacks: {} and {}",
|
||||
delicious_snacks::fruit,
|
||||
delicious_snacks::veggie,
|
||||
);
|
||||
}
|
||||
8
solutions/10_modules/modules3.rs
Normal file
8
solutions/10_modules/modules3.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn main() {
|
||||
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
||||
Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
|
||||
Err(_) => panic!("SystemTime before UNIX EPOCH!"),
|
||||
}
|
||||
}
|
||||
4
solutions/11_hashmaps/hashmaps1.rs
Normal file
4
solutions/11_hashmaps/hashmaps1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/11_hashmaps/hashmaps2.rs
Normal file
4
solutions/11_hashmaps/hashmaps2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/11_hashmaps/hashmaps3.rs
Normal file
4
solutions/11_hashmaps/hashmaps3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/12_options/options1.rs
Normal file
4
solutions/12_options/options1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/12_options/options2.rs
Normal file
4
solutions/12_options/options2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/12_options/options3.rs
Normal file
4
solutions/12_options/options3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/13_error_handling/errors1.rs
Normal file
4
solutions/13_error_handling/errors1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/13_error_handling/errors2.rs
Normal file
4
solutions/13_error_handling/errors2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/13_error_handling/errors3.rs
Normal file
4
solutions/13_error_handling/errors3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/13_error_handling/errors4.rs
Normal file
4
solutions/13_error_handling/errors4.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/13_error_handling/errors5.rs
Normal file
4
solutions/13_error_handling/errors5.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/13_error_handling/errors6.rs
Normal file
4
solutions/13_error_handling/errors6.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/14_generics/generics1.rs
Normal file
4
solutions/14_generics/generics1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/14_generics/generics2.rs
Normal file
4
solutions/14_generics/generics2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/15_traits/traits1.rs
Normal file
4
solutions/15_traits/traits1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/15_traits/traits2.rs
Normal file
4
solutions/15_traits/traits2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/15_traits/traits3.rs
Normal file
4
solutions/15_traits/traits3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/15_traits/traits4.rs
Normal file
4
solutions/15_traits/traits4.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/15_traits/traits5.rs
Normal file
4
solutions/15_traits/traits5.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/16_lifetimes/lifetimes1.rs
Normal file
4
solutions/16_lifetimes/lifetimes1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/16_lifetimes/lifetimes2.rs
Normal file
4
solutions/16_lifetimes/lifetimes2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/16_lifetimes/lifetimes3.rs
Normal file
4
solutions/16_lifetimes/lifetimes3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/17_tests/tests1.rs
Normal file
4
solutions/17_tests/tests1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/17_tests/tests2.rs
Normal file
4
solutions/17_tests/tests2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/17_tests/tests3.rs
Normal file
4
solutions/17_tests/tests3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/18_iterators/iterators1.rs
Normal file
4
solutions/18_iterators/iterators1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/18_iterators/iterators2.rs
Normal file
4
solutions/18_iterators/iterators2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/18_iterators/iterators3.rs
Normal file
4
solutions/18_iterators/iterators3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/18_iterators/iterators4.rs
Normal file
4
solutions/18_iterators/iterators4.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/18_iterators/iterators5.rs
Normal file
4
solutions/18_iterators/iterators5.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/19_smart_pointers/arc1.rs
Normal file
4
solutions/19_smart_pointers/arc1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/19_smart_pointers/box1.rs
Normal file
4
solutions/19_smart_pointers/box1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/19_smart_pointers/cow1.rs
Normal file
4
solutions/19_smart_pointers/cow1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/19_smart_pointers/rc1.rs
Normal file
4
solutions/19_smart_pointers/rc1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/20_threads/threads1.rs
Normal file
4
solutions/20_threads/threads1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/20_threads/threads2.rs
Normal file
4
solutions/20_threads/threads2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/20_threads/threads3.rs
Normal file
4
solutions/20_threads/threads3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/21_macros/macros1.rs
Normal file
4
solutions/21_macros/macros1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/21_macros/macros2.rs
Normal file
4
solutions/21_macros/macros2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/21_macros/macros3.rs
Normal file
4
solutions/21_macros/macros3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/21_macros/macros4.rs
Normal file
4
solutions/21_macros/macros4.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/22_clippy/clippy1.rs
Normal file
4
solutions/22_clippy/clippy1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/22_clippy/clippy2.rs
Normal file
4
solutions/22_clippy/clippy2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/22_clippy/clippy3.rs
Normal file
4
solutions/22_clippy/clippy3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/23_conversions/as_ref_mut.rs
Normal file
4
solutions/23_conversions/as_ref_mut.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/23_conversions/from_into.rs
Normal file
4
solutions/23_conversions/from_into.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/23_conversions/from_str.rs
Normal file
4
solutions/23_conversions/from_str.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/23_conversions/try_from_into.rs
Normal file
4
solutions/23_conversions/try_from_into.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/23_conversions/using_as.rs
Normal file
4
solutions/23_conversions/using_as.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
6
solutions/README.md
Normal file
6
solutions/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Official Rustlings solutions
|
||||
|
||||
Before you finish an exercise, its solution file will only contain an empty `main` function.
|
||||
The content of this file will be automatically replaced by the actual solution once you finish the exercise.
|
||||
|
||||
Note that these solutions are often only _one possibility_ to solve an exercise.
|
||||
30
solutions/quizzes/quiz1.rs
Normal file
30
solutions/quizzes/quiz1.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
// Mary is buying apples. The price of an apple is calculated as follows:
|
||||
// - An apple costs 2 rustbucks.
|
||||
// - However, if Mary buys more than 40 apples, the price of each apple in the
|
||||
// entire order is reduced to only 1 rustbuck!
|
||||
|
||||
fn calculate_price_of_apples(n_apples: u64) -> u64 {
|
||||
if n_apples > 40 {
|
||||
n_apples
|
||||
} else {
|
||||
2 * n_apples
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// You can optionally experiment here.
|
||||
}
|
||||
|
||||
// Don't change the tests!
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn verify_test() {
|
||||
assert_eq!(calculate_price_of_apples(35), 70);
|
||||
assert_eq!(calculate_price_of_apples(40), 80);
|
||||
assert_eq!(calculate_price_of_apples(41), 41);
|
||||
assert_eq!(calculate_price_of_apples(65), 65);
|
||||
}
|
||||
}
|
||||
4
solutions/quizzes/quiz2.rs
Normal file
4
solutions/quizzes/quiz2.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
4
solutions/quizzes/quiz3.rs
Normal file
4
solutions/quizzes/quiz3.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
Reference in New Issue
Block a user