← Back to context

Comment by thesuperbigfrog

3 hours ago

>> Also why Result<Option<T>>? Isn't Result already Option by itself?

No. I've written code that returns Result<Option<T>>. It was a wrapper for a server's query web API.

The Result part determines whether the request succeeded and the response is valid.

The Option part is because the parameter being queried might not exist. For example, if I ask the API for the current state of the user session with a given Session ID, but that Session ID does not exist, then the Rust wrapper could return OK(None) meaning that the request succeeded, but that no such session was found.

Presumably missing session is an alternative scenario and thus should be reported as an error, then you match and handle this error. Your design complicates the common scenario: in case of valid session you need double unwrap, cf File::open that could return Result<Option<File>> if file is not found.

  • >> Presumably missing session is an alternative scenario and thus should be reported as an error

    But in this case, a query using an invalid session ID is not an error. It is asking for details about something that does not exist.

    >> cf File::open that could return Result<Option<File>> if file is not found.

    This type of query is not like File::open which gets a handle to a resource. Trying to get a handle to a resource that does not exist is an error.

    This type of query is read-only and does not allocate any resources or prepare to do anything with the session.

    It simplifies the control flow because it distinguishes between errors in completing a query versus the presence or absence of items returned from the query.

Result is whether an operation returned an error or not. Option is whether you have a value or no value.

  • Exactly.

    That is why a query that successfully returns no items can be represented as Ok(None).

    A successful query with items returned would instead be Ok(Vec<Item>).

    An error in the completing the query (for example, problem with the database), would be Err(DatabaseError) or Err(SomeOtherError).