From ee3d6c88bb7e85c7f6c47b44ae663c8b5359c3e4 Mon Sep 17 00:00:00 2001 From: lilymonade Date: Tue, 11 Mar 2025 18:23:00 +0100 Subject: [PATCH] wip --- subject_source/tests/result.rs | 22 ++++++++++++ subject_text/errors/index.md | 2 +- subject_text/errors/result.md | 64 ++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 subject_source/tests/result.rs create mode 100644 subject_text/errors/result.md diff --git a/subject_source/tests/result.rs b/subject_source/tests/result.rs new file mode 100644 index 0000000..c373cf9 --- /dev/null +++ b/subject_source/tests/result.rs @@ -0,0 +1,22 @@ +use subject_source::errors::result; + + +#[test] +pub fn is_err_err() { + assert!(is_err(Err("oh no"))); +} + +#[test] +pub fn is_err_ok() { + assert!(!is_err(Ok(420))); +} + +#[test] +pub fn is_ok_err() { + assert!(!is_ok(Err("oh no"))); +} + +#[test] +pub fn is_ok_ok() { + assert!(is_ok(Ok(420))); +} diff --git a/subject_text/errors/index.md b/subject_text/errors/index.md index 627e9c3..4f8ac3e 100644 --- a/subject_text/errors/index.md +++ b/subject_text/errors/index.md @@ -1,6 +1,6 @@ --- name = "Errors" difficulty = 1 -exercises = ["option.md"] +exercises = ["option.md", "result.md"] --- diff --git a/subject_text/errors/result.md b/subject_text/errors/result.md new file mode 100644 index 0000000..f1769d4 --- /dev/null +++ b/subject_text/errors/result.md @@ -0,0 +1,64 @@ +--- +name = "Results" +file = "src/errors/result.rs" +--- + +We saw earlier the `Option` type, which represents a possibly absent value (sometimes called "nullable" in other languages). Now it would be useful to carry **the reason** of this absence of value. Let's say you are parsing an integer from a `String`, there are multiple ways it can fail. + +- The string contains invalid characters (non-digits). +- The value we want to parse is too large (for example, trying to parse `"999999999999"` as an i32). + +If we want to react properly, we need to know why it failed. So instead of having only `None` as output, we would like a variant like `SomeError(v)`. In Rust, this type with `Some` and `SomeError` variants is called [`Result`](https://doc.rust-lang.org/std/result/). + +Its variants are `Ok` and `Err`, and we can use it much like `Option`: + +```rust +// creating values of type Result +let itworked: Result = Ok(420); +let oops: Result = Err("badb002e"); + +// using values from Result +match itworked { + Ok(value) => println!("yes, we got {value}"), + Err(err) => eprintln!("oh no, some error occured: {err}"), +} +``` + +```prototype +/// Returns `true` if the result contains an `Err` +pub fn is_err(res: &Result) -> bool { + unimplemented!() +} + +/// Returns `true` if the result contains a `Ok` +pub fn is_ok(res: &Result) -> bool { + unimplemented!() +} + +/// Returns the wrapped `&str` if any, panic otherwise +pub fn get_err_or_panic(res: Result) -> &str { + unimplemented!() +} + +/// Returns the wrapped `i32` if any, panic otherwise +pub fn get_val_or_panic(res: Result) -> i32 { + unimplemented!() +} + +/// Transforms `Ok` to `Some` and `Err` to `None` +/// effectively discarding the `Err` wrapped value +pub fn discard_err(res: Result) -> Option { + unimplemented!() +} +``` + +```example +fn main() { + dbg!(is_err(Ok(10))); // false + dbg!(is_ok(Ok(128))); // true + dbg!(get_err_or_panic(Err("oh no"))); // "oh no" + dbg!(get_val_or_panic(Ok(420))); // 420 + dbg!(discard_err(Ok(69))); // Some(69) +} +``` +