Browse Source

Merge pull request #722 from 01-edu/rust-subject-review-quest-04

Rust subject review quest 04
content-update
augusto-mantilla 3 years ago committed by GitHub
parent
commit
5204f4df79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 76
      subjects/banner/README.md
  2. 100
      subjects/boxing_todo/README.md
  3. 4
      subjects/boxing_todo/malformed_object.json
  4. 27
      subjects/cipher/README.md
  5. 32
      subjects/error_types/README.md
  6. 29
      subjects/handling/README.md
  7. 16
      subjects/panic/README.md
  8. 59
      subjects/profanity_filter/README.md
  9. 32
      subjects/question_mark/README.md
  10. 84
      subjects/unwrap_or_expect/README.md

76
subjects/banner/README.md

@ -2,17 +2,16 @@
### Instructions ### Instructions
`Result` is a better version of the `Option` type that describes possible error instead "`Result` is a better version of the `Option` type that describes possible `error` instead of possible `absence`".
of possible absence
Create a structure called `Flag` that as the following elements: Create a structure called `Flag` which has the following elements:
- short_hand: String - short_hand: `String`
- long_hand: String - long_hand: `String`
- desc: String - desc: `String`
This structure must have associated to it a function called `opt_flag` that initializes the structure. This structure must have a **function** called `opt_flag` which initializes the structure.
Receiving two references strings and returns the structure `Flag`. It should be used like this: This **function** receives two strings references and returns a structure `Flag`. Here is an example of its usage:
```rust ```rust
let d = Flag::opt_flag("diff", "gives the difference between two numbers"); let d = Flag::opt_flag("diff", "gives the difference between two numbers");
@ -21,26 +20,40 @@ Receiving two references strings and returns the structure `Flag`. It should be
// output: "short hand: -d, long hand: --diff, description: gives the difference between two numbers" // output: "short hand: -d, long hand: --diff, description: gives the difference between two numbers"
``` ```
It will be given a second structure called `FlagsHandler` that has just one element: `flags: HashMap<(String, String), Callback>` A second structure called `FlagsHandler` will be given which just has one element: `flags: HashMap<(String, String), Callback>`
And the following functions associated to it, for you to complete : The following **functions** (methods) associated with `FlagsHandler` are for you to complete :
- `add_flag`, that adds to the HashMap the flag and the Callback function. - `add_flag`, which adds to the HashMap the flag and the Callback function.
- `exec_func`, that executes the function using the flag provided and returns the result, that can - `exec_func`, which executes the function using the flag provided and returns the result, which can be either a string with the value from the callback or an error.
be either a string with the value from the callback or an error.
It will also be provided a `type` called `Callback` being a function that is going to be used in the structure A `type` called `Callback` will also be provided. It is a function which is going to be used in the structure
and functions above. This function will be the callback for the flag associated to it. and functions above. This function will be the callback for the flag associated to it.
You will have to create the following callback functions : You will have to create the following callback functions :
- `div`, that converts the reference strings to `float`s and returns the `Result`, being the division of the `float`s or the standard (std) error: `ParseFloatError`. - `div` which converts the reference strings to `float`s and returns the `Result`, being the division of the `float`s or the standard (std) error: `ParseFloatError`.
- `rem`, that converts the reference strings to `float`s and returns the `Result`, being the remainder of the division of the `float`s or the standard (std) error `ParseFloatError`. - `rem` which converts the reference strings to `float`s and returns the `Result`, being the remainder of the division of the `float`s or the standard (std) error `ParseFloatError`.
### Notions
- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
- [Method optflag](https://docs.rs/getopts/0.2.18/getopts/struct.Options.html#method.optflag)
### Expected Function ### Expected Function
```rust ```rust
use std::collections::HashMap; use std::collections::HashMap;
pub struct Flag {
// expected public fields
}
impl Flag {
pub fn opt_flag(l_h: &str, d: &str) -> Flag {
}
}
pub type Callback = fn(&str, &str) -> Result<String, ParseFloatError>; pub type Callback = fn(&str, &str) -> Result<String, ParseFloatError>;
pub struct FlagsHandler { pub struct FlagsHandler {
@ -48,29 +61,31 @@ pub struct FlagsHandler {
} }
impl FlagsHandler { impl FlagsHandler {
pub fn add_flag(&mut self, flag: (String, String), func: Callback) {} pub fn add_flag(&mut self, flag: (String, String), func: Callback) {
pub fn exec_func(&mut self, flag: (String, String), argv: &[&str]) -> String {}
} }
} pub fn exec_func(&mut self, flag: (String, String), argv: &[&str]) -> String {
pub struct Flag { }
// expected public fields
} }
impl Flag { pub fn div(a: &str, b: &str) -> Result<String, ParseFloatError> {
pub fn opt_flag(l_h: &str, d: &str) -> Flag {}
} }
pub fn rem(a: &str, b: &str) -> Result<String, ParseFloatError> {
pub fn div(a: &str, b: &str) -> Result<String, ParseFloatError> {} }
pub fn rem(a: &str, b: &str) -> Result<String, ParseFloatError> {}
``` ```
### Usage ### Usage
Here is a program to test your function Here is a program to test your function:
```rust ```rust
use banner::*;
use std::collections::HashMap;
fn main() { fn main() {
let mut handler = FlagsHandler { flags: HashMap::new() }; let mut handler = FlagsHandler { flags: HashMap::new() };
@ -86,9 +101,9 @@ fn main() {
println!("{:?}", handler.exec_func(("-d".to_string(), "--division".to_string()), &["1.0", "2.0"])); println!("{:?}", handler.exec_func(("-d".to_string(), "--division".to_string()), &["1.0", "2.0"]));
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "2.0"])); println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "2.0"]));
println!("{:?}",handler.exec_func(("-d".to_string(), "--division".to_string()), &["a", "2.0"])); println!("{:?}",handler.exec_func(("-d".to_string(), "--division".to_string()), &["a", "2.0"]));
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "fd"])); println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "fd"]));
} }
``` ```
@ -103,8 +118,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
"invalid float literal" "invalid float literal"
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/rust-by-example/error/result.html
- https://docs.rs/getopts/0.2.18/getopts/struct.Options.html#method.optflag

100
subjects/boxing_todo/README.md

@ -2,49 +2,57 @@
### Instructions ### Instructions
The objective is to do an api to parse a list of *todos* that is organized in a JSON file, The objective is create an api to parse a list of _todos_ that is organized in a JSON file,
handling all possible errors in a multiple error system. handling all possible errors in a multiple error system.
Organization of the JSON file: Organization of the JSON file:
```json ```json
{ {
"title" : "TODO LIST FOR PISCINE RUST", "title": "TODO LIST FOR PISCINE RUST",
"tasks": [ "tasks": [
{ "id": 0, "description": "do this", "level": 0 }, { "id": 0, "description": "do this", "level": 0 },
{ "id": 1, "description": "do that", "level": 5 } { "id": 1, "description": "do that", "level": 5 }
] ]
} }
``` ```
Create a module in another file called **error.rs** that handles the boxing of errors. #### Error.rs
This module must implement an `enum` called `ParseErr` that will take care of the
parsing errors, it must have the following elements: Create a module in another file called **error.rs** which handles the boxing of errors.
This module must implement an `enum` called `ParseErr` which will take care of the
parsing errors. It must have the following elements:
- Empty - Empty
- Malformed, that has a dynamic boxed error as element - Malformed, which has a dynamic boxed error as element
A structure called `ReadErr` that will take care of the reading errors, having just an element called `child_err` of type `Box<dyn Error>`. A structure called `ReadErr` which will take care of the reading errors, having just an element called `child_err` of type `Box<dyn Error>`.
For each data structure you will have to implement a function called `fmt` for the trait `Display` that writes For each data structure you will have to implement a function called `fmt` for the trait `Display` which writes
out the message **"Fail to parse todo"** in case it's a parsing error, otherwise it writes the message out the message **"Failed to parse todo"** in case it is a parsing error. Otherwise, it should write the message
**"Failed to read todo file"**. **"Failed to read todo file"**.
And for the `Error` trait the following functions: For the `Error` trait the following functions (methods) have to be implemented:
- `description` that returns a string literal that says: - `source` which returns an `Option` with the error:
- "Todo List parse failed: " for the `ParseErr`
- "Todo List read failed: " for the `ReadErr`.
- `cause` that returns an `Option` with the error:
- For the `ReadErr` it must just return the option with the error - For the `ReadErr` it must just return the option with the error
- For the `ParseErr` it will return an option that can be `None` if the tasks are **empty** otherwise the error, if - For the `ParseErr` it will return an option which can be `None` if the tasks are **empty** otherwise the error, if
the parsing is **malformed**. the parsing is **malformed**.
#### lib.rs
In the **lib** file you will have to implement a **function** called `get_todo` which receives a string and returns a Result
which can be the structure `TodoList` or a boxing error. This **function** must be able to deserialize the json file.
Basically it must parse and read the JSON file and return the `TodoList` if everything is fine, otherwise it returns the error.
In the **lib** file you will have to implement a function called `get_todo` that receives a string and returns a Result ### Notions
that can be the structure `TodoList` or a boxing error. This function must be able to deserialize the json file,
basically it must parse and read the JSON file and return the `TodoList` if everything is fine otherwise the error. - [Module std::fmt](https://doc.rust-lang.org/std/fmt/)
- [JSON](https://docs.rs/json/0.12.4/json/)
- [Boxing errors](https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html)
- [Returning Traits wirh dyn](https://doc.rust-lang.org/stable/rust-by-example/trait/dyn.html)
### Expected Function ### Expected Functions
For **error.rs** For **error.rs**
@ -60,6 +68,7 @@ pub enum ParseErr {
// required by error trait // required by error trait
impl Display for ParseErr { impl Display for ParseErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
} }
} }
@ -70,19 +79,21 @@ pub struct ReadErr {
// required by error trait // required by error trait
impl Display for ReadErr { impl Display for ReadErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl Error for ReadErr { }
fn description(&self) -> &str {}
fn cause(&self) -> Option<&dyn Error> {}
} }
impl Error for ParseErr { impl Error for ParseErr {
fn description(&self) -> &str {} fn source(&self) -> Option<&(dyn Error + 'static)> {
fn cause(&self) -> Option<&dyn Error> {}
}
} }
impl Error for ReadErr {
fn source(&self) -> Option<&(dyn Error + 'static)> {
}
}
``` ```
for **lib.rs** for **lib.rs**
@ -90,24 +101,27 @@ for **lib.rs**
```rust ```rust
mod error; mod error;
use error::{ ParseErr, ReadErr }; use error::{ ParseErr, ReadErr };
use std::error::Error;
use serde::{ Deserialize, Serialize };
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] pub use json::{parse, stringify};
pub use std::error::Error;
#[derive(Debug, Eq, PartialEq)]
pub struct Task { pub struct Task {
id: u32, id: u32,
description: String, description: String,
level: u32, level: u32,
} }
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct TodoList { pub struct TodoList {
title: String, title: String,
tasks: Vec<Task>, tasks: Vec<Task>,
} }
impl TodoList { impl TodoList {
pub fn get_todo(path: &str) -> Result<TodoList, Box<dyn Error>> {} pub fn get_todo(path: &str) -> Result<TodoList, Box<dyn Error>> {
}
} }
``` ```
@ -126,7 +140,7 @@ fn main() {
match todos { match todos {
Ok(list) => println!("{:?}", list), Ok(list) => println!("{:?}", list),
Err(e) => { Err(e) => {
println!("{}{:?}", e.description(), e.cause()); println!("{}{:?}", e.to_string(), e.source());
} }
} }
@ -134,7 +148,7 @@ fn main() {
match todos { match todos {
Ok(list) => println!("{:?}", list), Ok(list) => println!("{:?}", list),
Err(e) => { Err(e) => {
println!("{}{:?}", e.description(), e.cause()); println!("{}{:?}", e.to_string(), e.source());
} }
} }
@ -142,7 +156,7 @@ fn main() {
match todos { match todos {
Ok(list) => println!("{:?}", list), Ok(list) => println!("{:?}", list),
Err(e) => { Err(e) => {
println!("{}{:?}", e.description(), e.cause().unwrap()); println!("{}{:?}", e.to_string(), e.source());
} }
} }
} }
@ -154,12 +168,6 @@ And its output:
student@ubuntu:~/[[ROOT]]/test$ cargo run student@ubuntu:~/[[ROOT]]/test$ cargo run
TodoList { title: "TODO LIST FOR PISCINE RUST", tasks: [Task { id: 0, description: "do this", level: 0 }, Task { id: 1, description: "do that", level: 5 }] } TodoList { title: "TODO LIST FOR PISCINE RUST", tasks: [Task { id: 0, description: "do this", level: 0 }, Task { id: 1, description: "do that", level: 5 }] }
Todo List parse failed: None Todo List parse failed: None
Todo List parse failed: Malformed(Error("missing field `title`", line: 1, column: 2)) Fail to parses todo Some(Malformed(UnexpectedCharacter { ch: ',', line: 2, column: 18 }))
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://serde.rs/
- https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
- https://doc.rust-lang.org/stable/rust-by-example/trait/dyn.html

4
subjects/boxing_todo/malformed_object.json

@ -1 +1,3 @@
{} {
"something": ,
}

27
subjects/cipher/README.md

@ -2,15 +2,18 @@
### Instructions ### Instructions
The Atbash cipher is a encryption method in which each letter of a word is replaced with its mirror letter in the alphabet The Atbash cipher is an encryption method in which each letter of a word is replaced by its mirror letter in the alphabet.
Your objective is to create a function called `cipher` this must return a Result wrapped in an Option, this result should return either a boolean Your objective is to create a **function** called `cipher` which must return a `Result` wrapped in an `Option`, this result should return either a `boolean`
or an Error being the structure `CipherError`. This structure should be the error type for the function `cipher` or an `Error` based on the structure `CipherError`. This structure should be the error type for the **function** `cipher`.
This function should compare the original string wih the ciphered string. returning true if the cipher is correct otherwise the error type This function should compare the original `String` with the ciphered `String`. It should return `true` if the cipher is correct. If the cipher is incorrect it should return the error type `CipherErr` with a `boolean` and the expected atbash cipher `String`.
CipherErr with the a true or false if it is validated and the proper atbash cipher.
### Expected Function ### Notions
- [Module std::fmt](https://doc.rust-lang.org/std/fmt/index.html)
### Expected Function and structure
```rust ```rust
@ -19,16 +22,22 @@ pub struct CipherError {
// expected public fields // expected public fields
} }
impl CipherError { impl CipherError {
pub fn new(validation: bool, expected: String) -> CipherError {} pub fn new(validation: bool, expected: String) -> CipherError {
}
}
pub fn cipher(original: &str, ciphered: &str) -> Option<Result<bool, CipherError>> {
} }
pub fn cipher(original: &str, ciphered: &str) -> Option<Result<bool, CipherError>> {}
``` ```
### Usage ### Usage
Here is a program to test your function Here is a program to test your function:
```rust ```rust
use cipher::*;
fn main() { fn main() {
println!("{:?}", cipher("1Hello 2world!", "1Svool 2dliow!")); println!("{:?}", cipher("1Hello 2world!", "1Svool 2dliow!"));
println!("{:?}", cipher("1Hello 2world!", "svool")); println!("{:?}", cipher("1Hello 2world!", "svool"));

32
subjects/error_type/README.md → subjects/error_types/README.md

@ -2,16 +2,16 @@
### Instructions ### Instructions
For this exercise you will have to implement an **error type**. For this exercise, you will have to implement an **error type**.
The main objective is to create a form validator, where you must implement a The main objective is to create a form validator, where you must implement an
error type. This must validate the password and the first name. The error type. This must validate the password and the first name. The
first name must not be empty and the password must have at least 8 char and a combination of alphanumeric and none alphanumeric ASCII characters first name must not be empty and the password must have **at least 8 char**, a **combination of alphanumeric**, **none-alphanumeric** (ex: <, & or /, ...)
ex: "asDd123=%" => good ex: "asDd123=%" => good (as 8 char, alphanumeric and non-alphanumeric)\
"asgfD" => error "asgfD" => error (does only have alphabetic letters)\
"asdsdf2" => error "asdsdf2" => error (missing none-alphanumeric)\
"sad_#$" => error "sad\_#$" => error (does not have a combination of alphanumeric)
Create a structure called `Form` that will have the following fields: Create a structure called `Form` that will have the following fields:
@ -30,8 +30,8 @@ It must have the fields:
- `form_values`, this will be a tuple of strings that will save the value that the user inserted into the form - `form_values`, this will be a tuple of strings that will save the value that the user inserted into the form
ex: ("password", "asdaSD_") ex: ("password", "asdaSD\_")
("first_name", "someone") ("first_name", "someone")
- `date`, that will have the date that the error occurred in the format "2020-12-14 09:33:41" - `date`, that will have the date that the error occurred in the format "2020-12-14 09:33:41"
- `err`, that will have the error description: - `err`, that will have the error description:
@ -39,6 +39,11 @@ ex: ("password", "asdaSD_")
- "At least 8 characters" - "At least 8 characters"
- "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)" - "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)"
### Notions
- [Error types](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/define_error_type.html)
- [Struct NaiveDate](https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDate.html)
### Expected Function ### Expected Function
```rust ```rust
@ -75,9 +80,11 @@ impl Form {
### Usage ### Usage
Here is a program to test your function Here is a program to test your function:
```rust ```rust
use error_types::*;
fn main() { fn main() {
let mut form_output = Form::new( let mut form_output = Form::new(
String::from("Alice"), String::from("Alice"),
@ -117,8 +124,3 @@ FErr { form_values: ("password", "asdasASd(_"), date: "2020-12-28 13:29:11", err
FErr { form_values: ("password", "asdasASd123SA"), date: "2020-12-28 13:29:11", err: "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)" } FErr { form_values: ("password", "asdasASd123SA"), date: "2020-12-28 13:29:11", err: "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)" }
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/define_error_type.html
- https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDate.html

29
subjects/handling/README.md

@ -2,18 +2,26 @@
### Instructions ### Instructions
Write a function, called `open_or_create` that as two arguments: Write a **function**, called `open_or_create` which has two arguments:
- `file : &str` which is the name of the files - `file : &str` which is the name of the file
- `content: &str` being the content to be written into the file - `content: &str` which will be the content to be written into the file
This functions should try to open a file, if it does not exist creates it. This function should try to open a file, if it does not exist, it should create it.
You should panic, with the error, in case something goes wrong. In case something goes wrong, it should panic, with the error.
### Notions
- [Error kind](https://doc.rust-lang.org/std/io/enum.ErrorKind.html)
- [struct file](https://doc.rust-lang.org/std/fs/struct.File.html)
- [OPenOptions](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html)
### Expected Function ### Expected Function
```rust ```rust
pub fn open_or_create(s: &str, content: &str) {} pub fn open_or_create(s: &str, content: &str) {
}
``` ```
### Usage ### Usage
@ -21,6 +29,10 @@ pub fn open_or_create(s: &str, content: &str) {}
Here is a program to test your function Here is a program to test your function
```rust ```rust
use std::fs::File;
use std::io::Read;
use handling::*;
fn main() { fn main() {
let path = "a.txt"; let path = "a.txt";
File::create(path).unwrap(); File::create(path).unwrap();
@ -41,8 +53,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
content to be written content to be written
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/std/io/enum.ErrorKind.html
- https://doc.rust-lang.org/std/fs/struct.File.html

16
subjects/panic/README.md

@ -2,20 +2,28 @@
### Instructions ### Instructions
Write a function that tries to open a file and panics if the file Write a **function** that tries to open a file and panics if the file
doesn't exist does not exist.
### Notions
### Expected Function ### Expected Function
```rust ```rust
pub fn open_file(s: &str) -> File {} pub fn open_file(s: &str) -> File {
}
``` ```
### Usage ### Usage
Here is a program to test your function Here is a program to test your function:
```rust ```rust
use std::fs::File;
use std::fs;
use panic::*;
fn main() { fn main() {
let filename = "created.txt"; let filename = "created.txt";
File::create(filename).unwrap(); File::create(filename).unwrap();

59
subjects/profanity_filter/README.md

@ -2,46 +2,56 @@
### Instructions ### Instructions
Sometimes it is more desirable to catch the failure of some parts of a program instead Sometimes it is more desirable to catch the failure of some parts of a program instead of just calling panic.
of just calling panic.
For this exercise you will have to create a message blocker, where you must block the word `stupid` For this exercise you will have to create a message blocker, where you must block the word `stupid`.
You will have to create a structure called `Message`, this structure You will have to create a structure called `Message`, this structure
must have the following elements: must have the following elements:
- content: String - content: String
- user: String - user: String
- time_sent: String
The struct must also have a implementation of 2 functions associated to it: The `struct` must also have a implementation of 2 **functions** associated with it:
- `new`, that initializes the structure - `new`, which initializes the structure
- `send_ms`, that only has its implementation type (**self**) as argument and returns an option. - `send_ms`, which only has its implementation type (**self**) as argument and returns an option:
This function must return `None` if the content of the message is either **empty** or contains the - This function must return `None` if the content of the message is either **empty** or contains the word **stupid**. Otherwise it returns the content of the message.
word **stupid**. Otherwise it returns the content of the message.
You will have to create two more functions that aren't associated to any structure: You will have to create two more **functions** that are not associated with any structure:
- `check_ms` that receives as parameters the reference to the structure `Message` and returns a tuple, - `check_ms` which:
containing a `bool` and a `string`. This function will execute the function `send_ms` and if the result - receives as parameters the reference to the structure `Message`
of the option is `None` it should return (false, "ERROR: illegal"). Otherwise it returns `true` and the - and returns a tuple, containing a `bool` and a `string`:
content of the message sent. - This function will execute the function `send_ms` and if the result of the option is `None`, it should return (false, "ERROR: illegal").Otherwise it returns `true` and the content of the message sent.
- `date_format` that creates and formats the date and time that the message was sent, the format should
look like this: **Mon Oct 5 10:22:19 2020** ### Notions
- [Enum Definition](https://doc.rust-lang.org/stable/book/ch06-01-defining-an-enum.html?highlight=option#the-option-enum-and-its-advantages-over-null-values)
### Expected Function ### Expected Function
```rust ```rust
pub struct Message {} pub struct Message {
}
impl Message { impl Message {
pub fn new(ms: String, u: String, t: String) -> Message {} pub fn new(ms: String, u: String, t: String) -> Message {
pub fn send_ms(&self) -> Option<&str> {}
}
pub fn send_ms(&self) -> Option<&str> {
}
}
pub fn check_ms(ms: &Message) -> (bool, &str) {
} }
pub fn check_ms(ms: &Message) -> (bool, &str) {} pub fn format_date() -> String {
pub fn format_date() -> String {}
}
``` ```
### Usage ### Usage
@ -49,6 +59,8 @@ pub fn format_date() -> String {}
Here is a program to test your function Here is a program to test your function
```rust ```rust
use profanity_filter::*;
fn main() { fn main() {
let m0 = Message::new("hello there".to_string(), "toby".to_string(), format_date()); let m0 = Message::new("hello there".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m0)); println!("{:?}", check_ms(&m0));
@ -74,8 +86,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
(false, "ERROR: illegal") (false, "ERROR: illegal")
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://docs.rs/chrono/0.4.19/chrono/
- https://doc.rust-lang.org/stable/book/ch06-01-defining-an-enum.html?highlight=option#the-option-enum-and-its-advantages-over-null-values

32
subjects/question_mark/README.md

@ -2,17 +2,25 @@
### Instructions ### Instructions
You will have to create 3 structures: 3 structure have to be created:
- `One`, that contains one element called `first_layer` it should be an `Option` for the structure `Two`. - `One`:
- `Two`, that contains one element called `second_layer` it should be an `Option` for the structure `Three`. - which contains one element called `first_layer` which should be an `Option` of the structure `Two`.
- `Three`, that contains one element called `third_layer` it should be an `Option` for the structure `Four`. - `Two`:
- `Four`, that contains one element called `fourth_layer` it should be an `u16` that is an `Option`. - which contains one element called `second_layer` which should be an `Option` of the structure `Three`.
- `Three`:
- which contains one element called `third_layer` which should be an `Option` of the structure `Four`.
- `Four`:
- which contains one element called `fourth_layer` which is an `Option<u16>`.
Beside the structure you must create a function named `get_fourth_layer` that is associated to the `One` structure. Beside the structure you must create a **function** named `get_fourth_layer` which is associated to the `One` structure (a method).
This function should return the `Option` value in the `Four` structure. This **function** should return the `Option` value in the `Four` structure.
### Expected Function ### Notions
- [Unpacking options with ?](https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap/question_mark.html)
### Expected Function and structures
```rust ```rust
pub struct One { pub struct One {
@ -35,9 +43,11 @@ impl One {
### Usage ### Usage
Here is a program to test your function Here is a program to test your function:
```rust ```rust
use question_mark::*;
fn main() { fn main() {
let a = One { let a = One {
first_layer : Some(Two { first_layer : Some(Two {
@ -64,7 +74,3 @@ student@ubuntu:~/[[ROOT]]/test$ cargo run
1000 1000
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap/question_mark.html

84
subjects/unwrap_or_expect/README.md

@ -1,48 +1,81 @@
## unwrap ## unwrap_or_expect
### Instructions ### Instructions
It will be given a function called **odd_to_even**, that returns an `Result`. If its an error it will A **function** called **odd_to_even** will be given, which returns a `Result`. If an error occurs the function will
return a tuple with a string, indicating the error, and a vector with the elements that justifies the error return a tuple with a string, stating the error, and a vector with the elements which causing the error.
The objective is to execute the `odd_to_even` function and handle the error given by it The objective is to execute the `odd_to_even` function and handle the error returned by it.
Create the following functions that receives a vector : Create the following functions which receives a vector :
- `expect` that returns the error adding the sting "ERROR " - `expect` which returns the error adding the string "ERROR "
- `unwrap_or` that in case of error returns an empty vector - `unwrap_or` which in case of error returns an empty vector
- `unwrap_err` that returns error if its `Ok` and returns the - `unwrap_err` which returns error if its `Ok` and returns the
string containing the error in case of `Err` string containing the error in case of `Err`
- `unwrap` that unwraps the `Result` - `unwrap` which unwraps the `Result`
- `unwrap_or_else` that in case of error returns a the vector that justifies the error - `unwrap_or_else` which in case of error returns the vector of elements which causes the error
### Expected Function ### Notions
- [Error Handling](https://doc.rust-lang.org/book/ch09-00-error-handling.html)
- [Unwrap keywords](https://doc.rust-lang.org/std/?search=unwrap)
### Expected Functions
```rust ```rust
pub fn odd_to_even(data: Vec<u32>) -> Result<Vec<u32>, (String, Vec<u32>)> {} pub fn odd_to_even(data: Vec<u32>) -> Result<Vec<u32>, (String, Vec<u32>)> {
pub fn expect(v: Vec<u32>) -> Vec<u32> {} let mut a = Vec::new();
pub fn unwrap_or(v: Vec<u32>) -> Vec<u32> {} a.extend(data.iter().filter(|&value| value % 2 == 0));
pub fn unwrap_err(v: Vec<u32>) -> (String, Vec<u32>) {} if a.len() != 0 {
pub fn unwrap(v: Vec<u32>) -> Vec<u32> {} return Err(("There is a even value in the vector!".to_string(), a));
pub fn unwrap_or_else(v: Vec<u32>) -> Vec<u32> {} }
a.extend(data.iter().map(|&value| {
value + 1
}));
Ok(a)
}
pub fn expect(v: Vec<u32>) -> Vec<u32> {
}
pub fn unwrap_or(v: Vec<u32>) -> Vec<u32> {
}
pub fn unwrap_err(v: Vec<u32>) -> (String, Vec<u32>) {
}
pub fn unwrap(v: Vec<u32>) -> Vec<u32> {
}
pub fn unwrap_or_else(v: Vec<u32>) -> Vec<u32> {
}
``` ```
### Usage ### Usage
Here is a program to test your function Here is a program to test your function:
```rust ```rust
use unwrap_or_expect::*;
fn main() { fn main() {
// this will give an expect error // // if uncommented, the below line will give an expect "ERROR "
// println!("{:?}", expect(vec![1, 3, 2, 5])); // println!("{:?}", expect(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or(vec![1, 3, 2, 5])); println!("{:?}", unwrap_or(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or(vec![1, 3, 5])); println!("{:?}", unwrap_or(vec![1, 3, 5]));
println!("{:?}", unwrap_err(vec![1, 3, 2, 5])); println!("{:?}", unwrap_err(vec![1, 3, 2, 5]));
// this will give an error that is unwraped
// // if uncommented, the below line will give an unwraped error
// println!("{:?}", unwrap_err(vec![1, 3, 5])); // println!("{:?}", unwrap_err(vec![1, 3, 5]));
println!("{:?}", unwrap(vec![1, 3, 5])); println!("{:?}", unwrap(vec![1, 3, 5]));
// this will give an error
//// if uncommented, the below line will give an error
// println!("{:?}", unwrap(vec![1, 3, 2, 5])); // println!("{:?}", unwrap(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or_else(vec![1, 3, 5])); println!("{:?}", unwrap_or_else(vec![1, 3, 5]));
println!("{:?}", unwrap_or_else(vec![3, 2, 6, 5])); println!("{:?}", unwrap_or_else(vec![3, 2, 6, 5]));
} }
@ -51,16 +84,13 @@ fn main() {
And its output: And its output:
```console ```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
[] []
[2, 4, 6] [2, 4, 6]
("There is a even value in the vector!", [2]) ("There is a even value in the vector!", [2])
[2, 4, 6] [2, 4, 6]
Ok([2, 4, 6])
[2, 4, 6] [2, 4, 6]
Err(("There is a even value in the vector!", [2, 6]))
[2, 6] [2, 6]
student@ubuntu:~/[[ROOT]]/test$ student@ubuntu:~/[[ROOT]]/test$
``` ```
### Notions
- https://doc.rust-lang.org/std/?search=unwrap

Loading…
Cancel
Save