# I am the Watcher. I am your guide through this vast new twtiverse.
# 
# Usage:
#     https://watcher.sour.is/api/plain/users              View list of users and latest twt date.
#     https://watcher.sour.is/api/plain/twt                View all twts.
#     https://watcher.sour.is/api/plain/mentions?uri=:uri  View all mentions for uri.
#     https://watcher.sour.is/api/plain/conv/:hash         View all twts for a conversation subject.
# 
# Options:
#     uri     Filter to show a specific users twts.
#     offset  Start index for quey.
#     limit   Count of items to return (going back in time).
# 
# twt range = 1 3
# self = https://watcher.sour.is/conv/a4qstxa
Okay, here’s a thing I like about Rust: Returning things as Option and error handling. (Or the more complex Result, but it’s easier to explain with Option.)

fn mydiv(num: f64, denom: f64) -> Option {
// (Let’s ignore precision issues for a second.)
if denom 0.0 {
return None;
} else {
return Some(num / denom);
}
}

fn main() {
// Explicit, verbose version:
let num: f64 = 123.0;
let denom: f64 = 456.0;
let wrapped_res = mydiv(num, denom);
if wrapped_res.is_some() {
println!("Unwrapped result: {}", wrapped_res.unwrap());
}

// Shorter version using "if let":
if let Some(res) = mydiv(123.0, 456.0) {
println!("Here’s a result: {}", res);
}

if let Some(res) = mydiv(123.0, 0.0) {
println!("Huh, we divided by zero? This never happens. {}", res);
}
}

You can’t divide by zero, so the function returns an “error” in that case. (Option isn’t really used for errors, IIUC, but the basic idea is the same for Result.)

`Option` is an enum. It can have the value Some or None. In the case of Some, *you can attach additional data* to the enum. In this case, we are attaching a floating point value.

The caller then has to decide: Is the value None or Some? Did the function succeed or not? If it is Some, the caller can do .unwrap() on this enum to get the inner value (the floating point value). If you do .unwrap() on a None value, the program will panic and die.

The if let version using destructuring is much shorter and, once you got used to it, actually quite nice.

Now the trick is that you *must* somehow handle these two cases. You *must* either call something like .unwrap() or do destructuring or something, otherwise you can’t access the attached value at all. As I understand it, it is impossible to just completely ignore error cases. And *the compiler enforces it*.

(In case of Result, the compiler would warn you if you ignore the return value entirely. So something like doing write() and then ignoring the return value would be caught as well.)
=
@prologic I’d say: Yes, because in Go it’s easier to ignore errors.

We’re talking about this pattern, right?

f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}

Nothing stops you from leaving out the if, right? 🤔
@lyse lol – I explicitly kept them in there so that the code is easier to understand for non-Rust people 🤪😂