Option says a value may be absent. ok_or turns absence into a Result with an explicit error value.

Program

Play the program to look up a selected setting and label missing keys.

key
option_to_result.rs
Replay: real traced execution (multi-file project)
fn lookup(key: &str) -> Result<&'static str, &'static str> {
    let value = match key {
        "host" => Some("local"),
        "port" => Some("8080"),
        _ => None,
    };
    value.ok_or("missing")
}

fn main() {
    let key = "host";
    let result = lookup(key);
    let label = match result {
        Ok(value) => format!("{key}={value}"),
        Err(error) => format!("{key}:{error}"),
    };
    println!("{label}");
}
fn lookup(key: &str) -> Result<&'static str, &'static str> {
    let value = match key {
        "host" => Some("local"),
        "port" => Some("8080"),
        _ => None,
    };
    value.ok_or("missing")
}

fn main() {
    let key = "port";
    let result = lookup(key);
    let label = match result {
        Ok(value) => format!("{key}={value}"),
        Err(error) => format!("{key}:{error}"),
    };
    println!("{label}");
}
fn lookup(key: &str) -> Result<&'static str, &'static str> {
    let value = match key {
        "host" => Some("local"),
        "port" => Some("8080"),
        _ => None,
    };
    value.ok_or("missing")
}

fn main() {
    let key = "debug";
    let result = lookup(key);
    let label = match result {
        Ok(value) => format!("{key}={value}"),
        Err(error) => format!("{key}:{error}"),
    };
    println!("{label}");
}
  1. key ← "host"

    10fn main() {11    let ke→ "host"y = "host"; //@key="host", "port", "debug"12    let result = lookup(ke"host"y);13    let label = match result {
  2. value ← Some("local")

    1fn lookup(key: &str) -> Result<&'static str, &'static str> {2    let valu→ Some("local")e = match ke"host"y {3        "host" => Some("local"),4        "port" => Some("8080"),5        _ => None,6    };7    value.ok_or("missing")8}
  3. result ← Ok("local"), label ← "host=local"

    11    let key = "host"; //@key="host", "port", "debug"12    let resul→ Ok("local")t = lookup(ke"host"y);13    let labe→ "host=local"l = match resulOk("local")t {14        Ok(value) => format!("{key}={value}"),15        Err(error) => format!("{key}:{error}"),16    };17    println!("{label}");18}
    outputhost=local
  1. key ← "port"

    10fn main() {11    let ke→ "port"y = "port";12    let result = lookup(ke"port"y);13    let label = match result {
  2. value ← Some("8080")

    1fn lookup(key: &str) -> Result<&'static str, &'static str> {2    let valu→ Some("8080")e = match ke"port"y {3        "host" => Some("local"),4        "port" => Some("8080"),5        _ => None,6    };7    value.ok_or("missing")8}
  3. result ← Ok("8080"), label ← "port=8080"

    11    let key = "port";12    let resul→ Ok("8080")t = lookup(ke"port"y);13    let labe→ "port=8080"l = match resulOk("8080")t {14        Ok(value) => format!("{key}={value}"),15        Err(error) => format!("{key}:{error}"),16    };17    println!("{label}");18}
    outputport=8080
  1. key ← "debug"

    10fn main() {11    let ke→ "debug"y = "debug";12    let result = lookup(ke"debug"y);13    let label = match result {
  2. value ← None

    1fn lookup(key: &str) -> Result<&'static str, &'static str> {2    let valu→ Nonee = match ke"debug"y {3        "host" => Some("local"),4        "port" => Some("8080"),5        _ => None,6    };7    value.ok_or("missing")8}
  3. result ← Err("missing"), label ← "debug:missing"

    11    let key = "debug";12    let resul→ Err("missing")t = lookup(ke"debug"y);13    let labe→ "debug:missing"l = match resulErr("missing")t {14        Ok(value) => format!("{key}={value}"),15        Err(error) => format!("{key}:{error}"),16    };17    println!("{label}");18}
    outputdebug:missing

Follow the Conversion

  1. A lookup starts as an Option.
  2. Some(value) means the key was present.
  3. None means the key was missing.
  4. ok_or turns the missing case into an Err. | Before ok_or | After ok_or | | --- | --- | | Some(value) | Ok(value) | | None | Err(message) |
Option `Option<T>` is either `Some(T)` or `None`.
ok_or `ok_or(error)` turns `Some` into `Ok` and `None` into `Err(error)`.
lookup result The caller gets a `Result` with a clear missing-key label.

Exercise: option_to_result.rs

Look up a required setting with ok_or and return a Result that names the missing key