Browse Source

quest-04: readme and tests

pull/692/head
lee 3 years ago
parent
commit
e170a345d0
  1. 12
      rust/tests/banner_test/Cargo.lock
  2. 10
      rust/tests/banner_test/Cargo.toml
  3. 88
      rust/tests/banner_test/src/main.rs
  4. 96
      rust/tests/boxing_todo_test/Cargo.lock
  5. 12
      rust/tests/boxing_todo_test/Cargo.toml
  6. 99
      rust/tests/boxing_todo_test/src/main.rs
  7. 12
      rust/tests/cipher_test/Cargo.lock
  8. 10
      rust/tests/cipher_test/Cargo.toml
  9. 24
      rust/tests/cipher_test/src/main.rs
  10. 98
      rust/tests/error_type_test/Cargo.lock
  11. 10
      rust/tests/error_type_test/Cargo.toml
  12. 136
      rust/tests/error_type_test/src/main.rs
  13. 12
      rust/tests/handling_test/Cargo.lock
  14. 10
      rust/tests/handling_test/Cargo.toml
  15. 1
      rust/tests/handling_test/a.txt
  16. 63
      rust/tests/handling_test/src/main.rs
  17. 12
      rust/tests/panic_test/Cargo.lock
  18. 10
      rust/tests/panic_test/Cargo.toml
  19. 29
      rust/tests/panic_test/src/main.rs
  20. 99
      rust/tests/profanity_filter_test/Cargo.lock
  21. 11
      rust/tests/profanity_filter_test/Cargo.toml
  22. 77
      rust/tests/profanity_filter_test/src/main.rs
  23. 12
      rust/tests/question_mark_test/Cargo.lock
  24. 10
      rust/tests/question_mark_test/Cargo.toml
  25. 47
      rust/tests/question_mark_test/src/main.rs
  26. 12
      rust/tests/unwrap_and_expect_test/Cargo.lock
  27. 10
      rust/tests/unwrap_and_expect_test/Cargo.toml
  28. 49
      rust/tests/unwrap_and_expect_test/src/main.rs
  29. 110
      subjects/banner/README.md
  30. 165
      subjects/boxing_todo/README.md
  31. 1
      subjects/boxing_todo/malformed_object.json
  32. 7
      subjects/boxing_todo/todo.json
  33. 4
      subjects/boxing_todo/todo_empty.json
  34. 47
      subjects/cipher/README.md
  35. 124
      subjects/error_type/README.md
  36. 48
      subjects/handling/README.md
  37. 34
      subjects/panic/README.md
  38. 81
      subjects/profanity_filter/README.md
  39. 70
      subjects/question_mark/README.md
  40. 66
      subjects/unwrap_or_expect/README.md

12
rust/tests/banner_test/Cargo.lock diff.generated

@ -0,0 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "banner"
version = "0.1.0"
[[package]]
name = "banner_test"
version = "0.1.0"
dependencies = [
"banner",
]

10
rust/tests/banner_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "banner_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
banner = { path = "../../../../rust-piscine-solutions/banner"}

88
rust/tests/banner_test/src/main.rs

@ -0,0 +1,88 @@
use std::collections::HashMap;
use banner::*;
fn main() {
let mut handler = FlagsHandler { flags: HashMap::new() };
let d = Flag::opt_flag("division", "divides the values, formula (a / b)");
let r = Flag::opt_flag(
"remainder",
"remainder of the division between two values, formula (a % b)",
);
handler.add_flag((d.short_hand, d.long_hand), div);
handler.add_flag((r.short_hand, r.long_hand), rem);
println!("{:?}", handler.exec_func(("-d".to_string(), "--division".to_string()), &["1.0", "2.0"]));
// output: "0.5"
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "2.0"]));
// output: "0.0"
println!("{:?}",handler.exec_func(("-d".to_string(), "--division".to_string()), &["a", "2.0"]));
// output: "invalid float literal"
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "fd"]));
// output: "invalid float literal"
}
#[cfg(test)]
mod tests {
use super::*;
fn init() -> FlagsHandler {
let d = Flag::opt_flag("division", "divides two numbers");
let r = Flag::opt_flag(
"remainder",
"gives the remainder of the division between two numbers",
);
let mut handler = FlagsHandler { flags: HashMap::new() };
handler.add_flag((d.short_hand, d.long_hand), div);
handler.add_flag((r.short_hand, r.long_hand), rem);
return handler;
}
#[test]
fn ok_test() {
let mut handler = init();
assert_eq!(
handler.exec_func(("-d".to_string(), "--division".to_string()), &["1.0", "2.0"]),
"0.5"
);
assert_eq!(
handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "2.0"]),
"0"
);
assert_eq!(
handler.exec_func(("-d".to_string(), "--division".to_string()), &["12.323", "212.32"]),
"0.05803975"
);
assert_eq!(
handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["12.323", "212.32"]),
"12.323"
);
}
#[test]
fn error_test() {
let mut handler = init();
assert_eq!(
handler.exec_func(("-d".to_string(), "--division".to_string()), &["a", "2.0"]),
"invalid float literal"
);
assert_eq!(
handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "f"]),
"invalid float literal"
);
assert_eq!(
handler.exec_func(("-d".to_string(), "--division".to_string()), &["1.0", "0.0"]),
"inf"
);
assert_eq!(
handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "0.0"]),
"NaN"
);
}
}

96
rust/tests/boxing_todo_test/Cargo.lock diff.generated

@ -0,0 +1,96 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "boxing_todo"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "boxing_todo_test"
version = "0.1.0"
dependencies = [
"boxing_todo",
"serde",
"serde_json",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9802ddde94170d186eeee5005b798d9c159fa970403f1be19976d0cfb939b72"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

12
rust/tests/boxing_todo_test/Cargo.toml

@ -0,0 +1,12 @@
[package]
name = "boxing_todo_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
boxing_todo = { path = "../../../../rust-piscine-solutions/boxing_todo"}
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

99
rust/tests/boxing_todo_test/src/main.rs

@ -0,0 +1,99 @@
use boxing_todo::*;
// Note that you can create some todo list your self to test it, but you can find the JSON files that
// are being tested [here](https://github.com/01-edu/public/blob/master/subjects/boxing_todo)
fn main() {
let todos = TodoList::get_todo("todo.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.description(), e.cause());
}
}
let todos = TodoList::get_todo("malforned_object.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.description(), e.cause().unwrap());
}
}
let todos = TodoList::get_todo("permission_err.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.description(), e.cause().unwrap());
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::fs;
fn new_todo(s: String, v: Vec<Task>) -> TodoList {
TodoList { title: s, tasks: v }
}
fn run(s: &TodoList, f: &str) -> Result<TodoList, Box<dyn Error>> {
serde_json::to_writer(&File::create(f)?, s)?;
let result = TodoList::get_todo(f);
fs::remove_file(f)?;
return result;
}
#[test]
fn test_good_todo() {
let file_name = "todo.json";
let good_struct = new_todo(
String::from("todo list for something"),
vec![
Task { id: 0, description: "do this".to_string(), level: 0 },
Task { id: 1, description: "do that".to_string(), level: 5 },
],
);
let result = run(&good_struct, file_name).unwrap();
assert_eq!(result.title, good_struct.title);
assert_eq!(&result.tasks, &good_struct.tasks);
}
#[test]
fn test_empty_tasks() {
let file_name = "empty_tasks.json";
let result = run(&new_todo(String::from("empty tasks"), vec![]), file_name).unwrap_err();
assert_eq!(result.to_string(), "Failed to parses todo");
assert_eq!(result.description(), "Todo List parse failed: ");
assert!(!result.cause().is_some());
}
#[test]
fn test_read() {
let result = TodoList::get_todo("no_file.json").unwrap_err();
assert_eq!(result.to_string(), "Failed to read todo file");
assert_eq!(result.description(), "Todo List read failed: ");
}
#[test]
#[should_panic(expected = "Malformed(Error(\"missing field `title`\", line: 1, column: 2))")]
fn test_malformed_json() {
#[derive(Serialize, Deserialize)]
struct Mal {};
let file_name = "malformed.json";
let malformed: Mal = serde_json::from_str(r#"{}"#).unwrap();
serde_json::to_writer(&File::create(file_name).unwrap(), &malformed).unwrap();
let result = TodoList::get_todo(file_name);
fs::remove_file(file_name).unwrap();
result.unwrap_or_else(|e| panic!("{:?}", e));
}
#[test]
#[should_panic(expected = "ReadErr { child_err: Os { code: 2, kind: NotFound, message: \"No such file or directory\" } }")]
fn test_read_error() {
TodoList::get_todo("no_file.json").unwrap_or_else(|e| panic!("{:?}", e));
}
}

12
rust/tests/cipher_test/Cargo.lock diff.generated

@ -0,0 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "cipher"
version = "0.1.0"
[[package]]
name = "cipher_test"
version = "0.1.0"
dependencies = [
"cipher",
]

10
rust/tests/cipher_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "cipher_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cipher = { path = "../../../../rust-piscine-solutions/cipher"}

24
rust/tests/cipher_test/src/main.rs

@ -0,0 +1,24 @@
use cipher::*;
fn main() {
println!("{:?}", cipher("1Hello 2world!", "1Svool 2dliow!"));
println!("{:?}", cipher("1Hello 2world!", "svool"));
println!("{:?}", cipher("", "svool"));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cipher() {
assert_eq!(cipher("1Hello 2world!", "1Svool 2dliow!"), Some(Ok(true)));
assert_eq!(cipher("", "1Svool 2dliow!"), None);
assert_eq!(cipher("1Hello 2world!", ""), None);
assert_eq!(cipher("1Hello 2world!", "1svool 2dliow!"), Some(Err(CipherError { validation: false, expected: String::from("1Svool 2dliow!") })));
assert_eq!(cipher("asdasd", "zhwzhw"), Some(Ok(true)));
assert_eq!(cipher("asdasd", "lkdas"), Some(Err(CipherError { validation: false, expected: String::from("zhwzhw") })));
assert_eq!(cipher("3(/&%fsd 32das", "3(/&%uhw 32wzh"), Some(Ok(true)));
assert_eq!(cipher("3(/&%sd 32das", "3(/&%uhw 32wzh"), Some(Err(CipherError { validation: false, expected: String::from("3(/&%hw 32wzh") })));
}
}

98
rust/tests/error_type_test/Cargo.lock diff.generated

@ -0,0 +1,98 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "error_type"
version = "0.1.0"
dependencies = [
"chrono",
]
[[package]]
name = "error_type_test"
version = "0.1.0"
dependencies = [
"error_type",
]
[[package]]
name = "libc"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

10
rust/tests/error_type_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "error_type_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
error_type = { path = "../../../../rust-piscine-solutions/error_type"}

136
rust/tests/error_type_test/src/main.rs

@ -0,0 +1,136 @@
use error_type::*;
#[allow(dead_code)]
fn create_date(date: &str) -> NaiveDate {
NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap()
}
fn main() {
let mut form_output = Form::new(
String::from("Lee"),
String::from("Silva"),
create_date("2015-09-05"),
SexType::Male,
String::from("Africa"),
String::from("qwqwsa1dty_"));
println!("{:?}", form_output);
println!("{:?}", form_output.validate().unwrap());
form_output.first_name = String::from("");
println!("{:?}", form_output.validate().unwrap_err());
form_output.first_name = String::from("as");
form_output.password = String::from("dty_1");
println!("{:?}", form_output.validate().unwrap_err());
form_output.password = String::from("asdasASd(_");
println!("{:?}", form_output.validate().unwrap_err());
form_output.password = String::from("asdasASd123SA");
println!("{:?}", form_output.validate().unwrap_err());
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug)]
struct TestForm<'a> {
form: Form,
validation: Result<Vec<&'a str>, FErr>
}
impl <'a> TestForm<'_> {
// all test cases
fn new() -> Vec<TestForm<'a>> {
vec![
TestForm {
form : Form::new(
String::from("Katy"),
String::from("Silva"),
create_date("2015-09-05"),
SexType::Female,
String::from("Africa"),
String::from("qwTw12&%$3sa1dty_")),
validation: Ok(vec!["Valid first name", "Valid password"]),
},
TestForm {
form : Form::new(
String::from(""),
String::from("Bear"),
create_date("2015-09-05"),
SexType::Male,
String::from("Africa"),
String::from("qwTw12&%$3sa1dty_")),
validation: Err(FErr {
form_values: (String::from("first_name"),
String::from("")),
date: Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(),
err: String::from("No user name")}),
},
TestForm {
form : Form::new(
String::from("Someone"),
String::from("Bear"),
create_date("2015-09-05"),
SexType::Male,
String::from("Africa"),
String::from("12345")),
validation: Err(FErr {
form_values: (String::from("password"), String::from("12345")),
date: Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(),
err: String::from("At least 8 characters") }),
},
TestForm {
form : Form::new(
String::from("Someone"),
String::from("Bear"),
create_date("2015-09-05"),
SexType::Male,
String::from("Africa"),
String::from("sdASDsrW")),
validation: Err(FErr {
form_values: (String::from("password"), String::from("sdASDsrW")),
date: Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(),
err: String::from("Combination of different ASCII character types (numbers, letters and none alphanumeric characters)") }),
},
TestForm {
form : Form::new(
String::from("Someone"),
String::from("Bear"),
create_date("2015-09-05"),
SexType::Female,
String::from("Africa"),
String::from("dsGE1SAD213")),
validation: Err(FErr {
form_values: (String::from("password"), String::from("dsGE1SAD213")),
date: Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(),
err: String::from("Combination of different ASCII character types (numbers, letters and none alphanumeric characters)") }),
},
TestForm {
form : Form::new(
String::from("Someone"),
String::from("Bear"),
create_date("2015-09-05"),
SexType::Female,
String::from("Africa"),
String::from("dsaSD&%DF!?=")),
validation: Err(FErr {
form_values: (String::from("password"), String::from("dsaSD&%DF!?=")),
date: Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(),
err: String::from("Combination of different ASCII character types (numbers, letters and none alphanumeric characters)") }),
}
]
}
}
#[test]
fn test_error_type() {
let form_cases = TestForm::new();
for v in form_cases {
assert_eq!(v.form.validate(), v.validation);
}
}
}

12
rust/tests/handling_test/Cargo.lock diff.generated

@ -0,0 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "handling"
version = "0.1.0"
[[package]]
name = "handling_test"
version = "0.1.0"
dependencies = [
"handling",
]

10
rust/tests/handling_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "handling_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handling = { path = "../../../../rust-piscine-solutions/handling"}

1
rust/tests/handling_test/a.txt

@ -0,0 +1 @@
content to be written

63
rust/tests/handling_test/src/main.rs

@ -0,0 +1,63 @@
use std::fs::{File, OpenOptions};
use std::io::prelude::*;
use std::io::{ErrorKind, Write};
use handling::*;
fn main() {
let path = "a.txt";
File::create(path).unwrap();
open_or_create(path, "content to be written");
let mut file = File::open(path).unwrap();
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
println!("{}", s);
// output: content to be written
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::panic;
fn get_file_content(filename: &str) -> String {
let mut file = File::open(filename).unwrap();
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
fs::remove_file(filename).unwrap();
return s;
}
#[test]
fn test_if_file_exists() {
let filename = "test_existing_file.txt";
let content = "hello world!";
File::create(filename).unwrap();
open_or_create(filename, content);
assert_eq!(content, get_file_content(filename));
}
#[test]
fn test_create_file() {
let file = "no_existing_file.txt";
let content = "hello world!";
open_or_create(file, content);
assert_eq!(content, get_file_content(file));
}
#[test]
fn test_error_case() {
let filename = "hello.txt";
File::create(filename).unwrap();
let mut perms = fs::metadata(filename).unwrap().permissions();
perms.set_readonly(true);
fs::set_permissions(filename, perms).unwrap();
let result = panic::catch_unwind(|| open_or_create(filename, "test"));
fs::remove_file(filename).unwrap();
assert!(result.is_err());
}
}

12
rust/tests/panic_test/Cargo.lock diff.generated

@ -0,0 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "panic"
version = "0.1.0"
[[package]]
name = "panic_test"
version = "0.1.0"
dependencies = [
"panic",
]

10
rust/tests/panic_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "panic_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
panic = { path = "../../../../rust-piscine-solutions/panic"}

29
rust/tests/panic_test/src/main.rs

@ -0,0 +1,29 @@
use panic::*;
use std::fs::{self, File};
fn main() {
let filename = "created.txt";
File::create(filename).unwrap();
let a = open_file(filename);
println!("{:?}", a);
fs::remove_file(filename).unwrap();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_opening() {
open_file("file.txt");
}
#[test]
fn test_opening_existing() {
let filename = "created.txt";
File::create(filename).unwrap();
open_file(filename);
fs::remove_file(filename).unwrap();
}
}

99
rust/tests/profanity_filter_test/Cargo.lock diff.generated

@ -0,0 +1,99 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "libc"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "profanity_filter"
version = "0.1.0"
dependencies = [
"chrono",
]
[[package]]
name = "profanity_filter_test"
version = "0.1.0"
dependencies = [
"chrono",
"profanity_filter",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

11
rust/tests/profanity_filter_test/Cargo.toml

@ -0,0 +1,11 @@
[package]
name = "profanity_filter_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
profanity_filter = { path = "../../../../rust-piscine-solutions/profanity_filter"}
chrono = "0.4.19"

77
rust/tests/profanity_filter_test/src/main.rs

@ -0,0 +1,77 @@
use profanity_filter::*;
fn main() {
let m0 = Message::new("hello there".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m0));
// output: (true, "hello there")
let m1 = Message::new("".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m1));
// output: (false, "ERROR: illegal")
let m2 = Message::new("you are stupid".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m2));
// output: (false, "ERROR: illegal")
let m3 = Message::new("stupid".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m3));
// output: (false, "ERROR: illegal")
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::prelude::Utc;
fn test_format() -> String {
Utc::now().format("%a %b %e %T %Y").to_string()
}
#[test]
fn test_time_format() {
assert_eq!(format_date(), test_format());
}
#[test]
fn test_error_ms() {
let v = vec![
Message::new("".to_string(), "toby".to_string(), format_date()),
Message::new("stupid".to_string(), "jack".to_string(), format_date()),
Message::new(
"you are stupid".to_string(),
"jacob".to_string(),
format_date(),
),
];
for value in v {
let (t, _) = check_ms(&value);
assert!(!t);
}
}
#[test]
fn test_ok_ms() {
let v = vec![
Message::new(
"get out of the car".to_string(),
"police".to_string(),
format_date(),
),
Message::new("no!".to_string(), "thief".to_string(), format_date()),
Message::new(
"get the werewolf".to_string(),
"police".to_string(),
format_date(),
),
Message::new(
"wait the wha...".to_string(),
"thief".to_string(),
format_date(),
),
];
for value in v {
let (t, _) = check_ms(&value);
assert!(t);
}
}
}

12
rust/tests/question_mark_test/Cargo.lock diff.generated

@ -0,0 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "question_mark"
version = "0.1.0"
[[package]]
name = "question_mark_test"
version = "0.1.0"
dependencies = [
"question_mark",
]

10
rust/tests/question_mark_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "question_mark_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
question_mark = { path = "../../../../rust-piscine-solutions/question_mark"}

47
rust/tests/question_mark_test/src/main.rs

@ -0,0 +1,47 @@
use question_mark::*;
fn main() {
let a = One {
first_layer : Some(Two {
second_layer: Some(Three {
third_layer: Some(Four {
fourth_layer: Some(1000)
})
})
})
};
// output: 1000
println!("{:?}", match a.get_fourth_layer() {
Some(e) => e,
None => 0
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_value() {
let a = One {
first_layer : Some(Two {
second_layer: Some(Three {
third_layer: Some(Four {
fourth_layer: Some(1000)
})
})
})
};
let b = One {
first_layer : Some(Two {
second_layer: Some(Three {
third_layer: Some(Four {
fourth_layer: Some(3)
})
})
})
};
assert_eq!(a.get_fourth_layer(), Some(1000));
assert_eq!(b.get_fourth_layer(), Some(3));
}
}

12
rust/tests/unwrap_and_expect_test/Cargo.lock diff.generated

@ -0,0 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "unwrap_and_expect"
version = "0.1.0"
[[package]]
name = "unwrap_and_expect_test"
version = "0.1.0"
dependencies = [
"unwrap_and_expect",
]

10
rust/tests/unwrap_and_expect_test/Cargo.toml

@ -0,0 +1,10 @@
[package]
name = "unwrap_and_expect_test"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
unwrap_and_expect = { path = "../../../../rust-piscine-solutions/unwrap_and_expect"}

49
rust/tests/unwrap_and_expect_test/src/main.rs

@ -0,0 +1,49 @@
use unwrap_and_expect::*;
fn main() {
println!("{:?}", unwrap_or(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or(vec![1, 3, 5]));
println!("{:?}", unwrap_err(vec![1, 3, 2, 5]));
println!("{:?}", unwrap(vec![1, 3, 5]));
println!("{:?}", unwrap_or_else(vec![1, 3, 5]));
println!("{:?}", unwrap_or_else(vec![3, 2, 6, 5]));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic(expected = "ERROR : (\"There is a even value in the vector!\", [2])")]
fn test_expect() {
expect(vec![1, 3, 2, 5]);
}
#[test]
#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: (\"There is a even value in the vector!\", [2])")]
fn test_unwrap() {
unwrap(vec![1, 3, 2, 5]);
}
#[test]
#[should_panic]
fn test_unwrap_err() {
unwrap_err(vec![1, 3, 5]);
}
#[test]
fn test_unwrap_or() {
assert_eq!(unwrap_or(vec![1, 3, 2, 5]), vec![]);
}
#[test]
fn test_unwrap_or_else() {
assert_eq!(unwrap_or_else(vec![1, 3, 5]), vec![2, 4, 6]);
assert_eq!(unwrap_or_else(vec![6, 8, 3, 2, 5, 4]), vec![6, 8, 2, 4]);
}
#[test]
fn test_ok() {
assert_eq!(expect(vec![1, 3, 5]), vec![2, 4, 6]);
assert_eq!(unwrap_or(vec![1, 3, 5]), vec![2, 4, 6]);
assert_eq!(unwrap_or_else(vec![1, 3, 5]), vec![2, 4, 6]);
assert_eq!(unwrap(vec![1, 3, 5]), vec![2, 4, 6]);
assert_eq!(unwrap_err(vec![1, 2, 3, 4, 5]).0, "There is a even value in the vector!");
assert_eq!(unwrap_err(vec![1, 2, 3, 4, 5]).1, vec![2, 4]);
}
}

110
subjects/banner/README.md

@ -0,0 +1,110 @@
## banner
### Instructions
`Result` is a better version of the `Option` type that describes possible error instead
of possible absence
Create a structure called `Flag` that as the following elements:
- short_hand: String
- long_hand: String
- desc: String
This structure must have associated to it a function called `opt_flag` that initializes the structure.
Receiving two references strings and returns the structure `Flag`. It should be used like this:
```rust
let d = Flag::opt_flag("diff", "gives the difference between two numbers");
println!("short hand: {}, long hand: {}, description: {}", d.short_hand, d.long_hand, d.desc);
// 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>`
And the following functions associated to it, for you to complete :
- `add_flag`, that 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
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
and functions above. This function will be the callback for the flag associated to it.
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`.
- `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`.
### Expected Function
```rust
use std::collections::HashMap;
pub type Callback = fn(&str, &str) -> Result<String, ParseFloatError>;
pub struct FlagsHandler {
pub flags: HashMap<(String, String), Callback>,
}
impl FlagsHandler {
pub fn add_flag(&mut self, flag: (String, String), func: Callback) {}
pub fn exec_func(&mut self, flag: (String, String), argv: &[&str]) -> String {}
}
}
pub struct Flag {
// expected public fields
}
impl Flag {
pub fn opt_flag(l_h: &str, d: &str) -> Flag {}
}
pub fn div(a: &str, b: &str) -> Result<String, ParseFloatError> {}
pub fn rem(a: &str, b: &str) -> Result<String, ParseFloatError> {}
```
### Usage
Here is a program to test your function
```rust
fn main() {
let mut handler = FlagsHandler { flags: HashMap::new() };
let d = Flag::opt_flag("division", "divides the values, formula (a / b)");
let r = Flag::opt_flag(
"remainder",
"remainder of the division between two values, formula (a % b)",
);
handler.add_flag((d.short_hand, d.long_hand), div);
handler.add_flag((r.short_hand, r.long_hand), rem);
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(("-d".to_string(), "--division".to_string()), &["a", "2.0"]));
println!("{:?}",handler.exec_func(("-r".to_string(), "--remainder".to_string()), &["2.0", "fd"]));
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
"0.5"
"0"
"invalid float literal"
"invalid float literal"
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

165
subjects/boxing_todo/README.md

@ -0,0 +1,165 @@
## boxing_todo
### Instructions
The objective is to do an api to parse a list of *todos* that is organized in a JSON file,
handling all possible errors in a multiple error system.
Organization of the JSON file:
```json
{
"title" : "TODO LIST FOR PISCINE RUST",
"tasks": [
{ "id": 0, "description": "do this", "level": 0 },
{ "id": 1, "description": "do that", "level": 5 }
]
}
```
Create a module in another file called **error.rs** that handles the boxing of errors.
This module must implement an `enum` called `ParseErr` that will take care of the
parsing errors, it must have the following elements:
- Empty
- Malformed, that 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>`.
For each data structure you will have to implement a function called `fmt` for the trait `Display` that writes
out the message **"Fail to parse todo"** in case it's a parsing error, otherwise it writes the message
**"Failed to read todo file"**.
And for the `Error` trait the following functions:
- `description` that returns a string literal that says:
- "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 `ParseErr` it will return an option that can be `None` if the tasks are **empty** otherwise the error, if
the parsing is **malformed**.
In the **lib** file you will have to implement a function called `get_todo` that receives a string and returns a Result
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.
### Expected Function
For **error.rs**
```rust
use std::fmt;
use std::fmt::Display;
use std::error::Error;
pub enum ParseErr {
// expected public fields
}
// required by error trait
impl Display for ParseErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
pub struct ReadErr {
// expected public fields
}
// required by error trait
impl Display for ReadErr {
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 {
fn description(&self) -> &str {}
fn cause(&self) -> Option<&dyn Error> {}
}
```
for **lib.rs**
```rust
mod error;
use error::{ ParseErr, ReadErr };
use std::error::Error;
use serde::{ Deserialize, Serialize };
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct Task {
id: u32,
description: String,
level: u32,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct TodoList {
title: String,
tasks: Vec<Task>,
}
impl TodoList {
pub fn get_todo(path: &str) -> Result<TodoList, Box<dyn Error>> {}
}
```
### Usage
Here is a program to test your function.
Note that you can create some todo list your self to test it, but you can find the JSON files that
are being tested [here](https://github.com/01-edu/public/blob/master/subjects/boxing_todo)
```rust
mod lib;
use lib::{ TodoList };
fn main() {
let todos = TodoList::get_todo("todo.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.description(), e.cause());
}
}
let todos = TodoList::get_todo("no_todo_list.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.description(), e.cause());
}
}
let todos = TodoList::get_todo("malformed_object.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.description(), e.cause().unwrap());
}
}
}
```
And its output:
```console
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 }] }
Todo List parse failed: None
Todo List parse failed: Malformed(Error("missing field `title`", line: 1, column: 2))
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

1
subjects/boxing_todo/malformed_object.json

@ -0,0 +1 @@
{}

7
subjects/boxing_todo/todo.json

@ -0,0 +1,7 @@
{
"title" : "TODO LIST FOR PISCINE RUST",
"tasks": [
{ "id": 0, "description": "do this", "level": 0 },
{ "id": 1, "description": "do that", "level": 5 }
]
}

4
subjects/boxing_todo/todo_empty.json

@ -0,0 +1,4 @@
{
"title" : "TODO LIST FOR PISCINE RUST",
"tasks": []
}

47
subjects/cipher/README.md

@ -0,0 +1,47 @@
## cipher
### Instructions
The Atbash cipher is a encryption method in which each letter of a word is replaced with 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
or an Error being 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
CipherErr with the a true or false if it is validated and the proper atbash cipher.
### Expected Function
```rust
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct CipherError {
// expected public fields
}
impl CipherError {
pub fn new(validation: bool, expected: String) -> CipherError {}
}
pub fn cipher(original: &str, ciphered: &str) -> Option<Result<bool, CipherError>> {}
```
### Usage
Here is a program to test your function
```rust
fn main() {
println!("{:?}", cipher("1Hello 2world!", "1Svool 2dliow!"));
println!("{:?}", cipher("1Hello 2world!", "svool"));
println!("{:?}", cipher("", "svool"));
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
Some(Ok(true))
Some(Err(CipherError { validation: false, expected: "1Svool 2dliow!" }))
None
student@ubuntu:~/[[ROOT]]/test$
```

124
subjects/error_type/README.md

@ -0,0 +1,124 @@
## error types
### Instructions
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
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
ex: "asDd123=%" => good
"asgfD" => error
"asdsdf2" => error
"sad_#$" => error
Create a structure called `Form` that will have the following fields:
- `first_name`, that will be a string
- `last_name`, that will be a string
- `birth`, of type `NaiveDate` that will convert a string "2015-09-05" to a date of that format
- `sex`, SexType that must be a `enum` with the fields `Male` and `Female`
- `birth_location`, that will be a string
- `password`, that will be a string
You must also implement for this structure a function to initialize the structure, `new` and a function called
`validate` that will validate the form
For the error type you must create a type struct called `FErr`, that will be the type for the error
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
ex: ("password", "asdaSD_")
("first_name", "someone")
- `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:
- "No user name"
- "At least 8 characters"
- "Combination of different ASCII character types (numbers, letters and none alphanumeric characters)"
### Expected Function
```rust
pub use chrono::{Utc, NaiveDate};
// this will be the structure that wil handle the errors
#[derive(Debug, Eq, PartialEq)]
pub struct FErr {
// expected public fields
}
impl FErr {
pub fn new(name: String, error: String, err: String) -> FErr {}
}
#[derive(Debug, Eq, PartialEq)]
pub enum SexType {
// expected public fields
}
#[derive(Debug, Eq, PartialEq)]
pub struct Form {
// expected public fields
}
impl Form {
pub fn new(first_name: String,
last_name: String,
birth: NaiveDate,
sex: SexType,
birth_location: String,
password: String) -> Form {}
pub fn validate(&self) -> Result<Vec<&str>, FErr> {}
}
```
### Usage
Here is a program to test your function
```rust
fn main() {
let mut form_output = Form::new(
String::from("Alice"),
String::from("Bear"),
create_date("2015-09-05"),
SexType::Male,
String::from("Africa"),
String::from("qwqwsa1dty_"));
println!("{:?}", form_output);
println!("{:?}", form_output.validate().unwrap());
form_output.first_name = String::from("");
println!("{:?}", form_output.validate().unwrap_err());
form_output.first_name = String::from("as");
form_output.password = String::from("dty_1");
println!("{:?}", form_output.validate().unwrap_err());
form_output.password = String::from("asdasASd(_");
println!("{:?}", form_output.validate().unwrap_err());
form_output.password = String::from("asdasASd123SA");
println!("{:?}", form_output.validate().unwrap_err());
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
Form { first_name: "Lee", last_name: "Silva", birth: 2015-09-05, sex: Male, birth_location: "Africa", password: "qwqwsa1dty_" }
["Valid first name", "Valid password"]
FErr { form_values: ("first_name", ""), date: "2020-12-28 13:29:11", err: "No user name" }
FErr { form_values: ("password", "dty_1"), date: "2020-12-28 13:29:11", err: "At least 8 characters" }
FErr { form_values: ("password", "asdasASd(_"), 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$
```
### 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

48
subjects/handling/README.md

@ -0,0 +1,48 @@
## handling
### Instructions
Write a function, called `open_or_create` that as two arguments:
- `file : &str` which is the name of the files
- `content: &str` being the content to be written into the file
This functions should try to open a file, if it does not exist creates it.
You should panic, with the error, in case something goes wrong.
### Expected Function
```rust
pub fn open_or_create(s: &str, content: &str) {}
```
### Usage
Here is a program to test your function
```rust
fn main() {
let path = "a.txt";
File::create(path).unwrap();
open_or_create(path, "content to be written");
let mut file = File::open(path).unwrap();
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
println!("{}", s);
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
content to be written
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

34
subjects/panic/README.md

@ -0,0 +1,34 @@
## panic
### Instructions
Write a function that tries to open a file and panics if the file
doesn't exist
### Expected Function
```rust
pub fn open_file(s: &str) -> File {}
```
### Usage
Here is a program to test your function
```rust
fn main() {
let filename = "created.txt";
File::create(filename).unwrap();
let a = open_file(filename);
println!("{:?}", a);
fs::remove_file(filename).unwrap();
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
File { fd: 3, path: "[[ROOT]]/a.txt", read: true, write: false }
student@ubuntu:~/[[ROOT]]/test$
```

81
subjects/profanity_filter/README.md

@ -0,0 +1,81 @@
## profanity filter
### Instructions
Sometimes it is more desirable to catch the failure of some parts of a program instead
of just calling panic.
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
must have the following elements:
- content: String
- user: String
- time_sent: String
The struct must also have a implementation of 2 functions associated to it:
- `new`, that initializes the structure
- `send_ms`, that 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
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:
- `check_ms` that receives as parameters the reference to the structure `Message` and returns a tuple,
containing a `bool` and a `string`. 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**
### Expected Function
```rust
pub struct Message {}
impl Message {
pub fn new(ms: String, u: String, t: String) -> Message {}
pub fn send_ms(&self) -> Option<&str> {}
}
pub fn check_ms(ms: &Message) -> (bool, &str) {}
pub fn format_date() -> String {}
```
### Usage
Here is a program to test your function
```rust
fn main() {
let m0 = Message::new("hello there".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m0));
let m1 = Message::new("".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m1));
let m2 = Message::new("you are stupid".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m2));
let m3 = Message::new("stupid".to_string(), "toby".to_string(), format_date());
println!("{:?}", check_ms(&m3));
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
(true, "hello there")
(false, "ERROR: illegal")
(false, "ERROR: illegal")
(false, "ERROR: illegal")
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

70
subjects/question_mark/README.md

@ -0,0 +1,70 @@
## question_mark
### Instructions
You will have to create 3 structures:
- `One`, that contains one element called `first_layer` it should be an `Option` for the structure `Two`.
- `Two`, that contains one element called `second_layer` it should be an `Option` for the structure `Three`.
- `Three`, that contains one element called `third_layer` it should be an `Option` for the structure `Four`.
- `Four`, that contains one element called `fourth_layer` it should be an `u16` that is an `Option`.
Beside the structure you must create a function named `get_fourth_layer` that is associated to the `One` structure.
This function should return the `Option` value in the `Four` structure.
### Expected Function
```rust
pub struct One {
// expected public fields
}
pub struct Two {
// expected public fields
}
pub struct Three {
// expected public fields
}
pub struct Four {
// expected public fields
}
impl One {
pub fn get_fourth_layer(&self) -> Option<u16> {}
}
```
### Usage
Here is a program to test your function
```rust
fn main() {
let a = One {
first_layer : Some(Two {
second_layer: Some(Three {
third_layer: Some(Four {
fourth_layer: Some(1000)
})
})
})
};
// output: 1000
println!("{:?}", match a.get_fourth_layer() {
Some(e) => e,
None => 0
})
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
1000
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap/question_mark.html

66
subjects/unwrap_or_expect/README.md

@ -0,0 +1,66 @@
## unwrap
### Instructions
It will be given a function called **odd_to_even**, that returns an `Result`. If its an error it will
return a tuple with a string, indicating the error, and a vector with the elements that justifies the error
The objective is to execute the `odd_to_even` function and handle the error given by it
Create the following functions that receives a vector :
- `expect` that returns the error adding the sting "ERROR "
- `unwrap_or` that in case of error returns an empty vector
- `unwrap_err` that returns error if its `Ok` and returns the
string containing the error in case of `Err`
- `unwrap` that unwraps the `Result`
- `unwrap_or_else` that in case of error returns a the vector that justifies the error
### Expected Function
```rust
pub fn odd_to_even(data: Vec<u32>) -> Result<Vec<u32>, (String, Vec<u32>)> {}
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
Here is a program to test your function
```rust
fn main() {
// this will give an expect error
// println!("{:?}", expect(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or(vec![1, 3, 5]));
println!("{:?}", unwrap_err(vec![1, 3, 2, 5]));
// this will give an error that is unwraped
// println!("{:?}", unwrap_err(vec![1, 3, 5]));
println!("{:?}", unwrap(vec![1, 3, 5]));
// this will give an error
// println!("{:?}", unwrap(vec![1, 3, 2, 5]));
println!("{:?}", unwrap_or_else(vec![1, 3, 5]));
println!("{:?}", unwrap_or_else(vec![3, 2, 6, 5]));
}
```
And its output:
```console
student@ubuntu:~/[[ROOT]]/test$ cargo run
[]
[2, 4, 6]
("There is a even value in the vector!", [2])
[2, 4, 6]
[2, 4, 6]
[2, 6]
student@ubuntu:~/[[ROOT]]/test$
```
### Notions
- https://doc.rust-lang.org/std/?search=unwrap
Loading…
Cancel
Save