result-exos #1

Merged
lilymonade merged 4 commits from result-exos into main 2025-03-11 17:43:29 +00:00
3 changed files with 87 additions and 1 deletions
Showing only changes of commit ee3d6c88bb - Show all commits

View File

@ -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)));
}

View File

@ -1,6 +1,6 @@
---
name = "Errors"
difficulty = 1
exercises = ["option.md"]
exercises = ["option.md", "result.md"]
---

View File

@ -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<i32, &str> = Ok(420);
let oops: Result<i32, &str> = 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<i32, &str>) -> bool {
unimplemented!()
}
/// Returns `true` if the result contains a `Ok`
pub fn is_ok(res: &Result<i32, &str>) -> bool {
unimplemented!()
}
/// Returns the wrapped `&str` if any, panic otherwise
pub fn get_err_or_panic(res: Result<i32, &str>) -> &str {
unimplemented!()
}
/// Returns the wrapped `i32` if any, panic otherwise
pub fn get_val_or_panic(res: Result<i32, &str>) -> i32 {
unimplemented!()
}
/// Transforms `Ok` to `Some` and `Err` to `None`
/// effectively discarding the `Err` wrapped value
pub fn discard_err(res: Result<i32, &str>) -> Option<i32> {
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)
}
```