I don’t quite fully understand yet but from as much as I know already after implementing around 10 functions in Rust I could say that I least I know how to use the Result type which is has the following definition Result<T, E>, which contains Ok and Err values, I say values because those two as for documentation say are values but I see an Enum like follows:

pub enum Result<T, E> {
    Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
    Err(#[stable(feature = "rust1", since = "1.0.0")] E),
}

Which honestly is something else very useful as a feature because you can override bitwise operations for enums and use like follows, I might be amazed of this feature because coming from Go is like at least am able to create some complexity which for now I don’t know over-engineering. Check this next piece of code for using composed enums like follows which when I made this was like without quite intending and was like wow.

self.check_permission(
  &req,
   Write(User("profile".to_string())) |
   Read(User(user.id.to_string())) |
   Write(User(user.id.to_string()))
).await?;

My experience is from PHP where I played with OOP, design patterns and architecture, one of my favorite patterns is composition which pulls me more in the past to a relics like Flash AS3, stepping back to present architecture is still great to visualize and build up, and Rust… I can’t say much of it because is too early, if what they say is like C/C++ then have a language like that with cargo tooling and with those features reveals a new kind of experience which for me from Go is like changing from running to meditation, anyway, as you can see in the previous code example using something like you see there with write, read, is clean, easy to read, and you can express in a simple way yet complex underneath which I like, and its actually simple to allow pipe or symbol which is by implementing bitor function from std::ops::BitOr.

So a way of using a function that returns result is like the previous example where await? is used which returns the T or propagates further in the current context the E, another way is by using .unwrap() which is something you have to pay attention because throws an exception, you can see real life problem here where is about cloudflare. Besides that, another way is, and the most clean one from my little knowledge of Rust is use of match:

let result = match get_user().await {
    Ok(user) => user,
    Err(e) => Err(e)
};

This way is like treating each error so you have to know when to use ? and when to use match, and this “you have to know” is like the thing of Rust which demands your presence and attention.