Functions for Result<T, E> -> Result<T, F>

I am aware of

pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F> {

https://doc.rust-lang.org/src/core/result.rs.html#588

Is there a way to specify a raw value for F (rather than a function that returns a F), or does this not matter since via zero cost abstractions, if we provide a function at compile time, it is optimized away ?

EDIT: I realize this can be trivially solved via match, but was wondering if there is a builtin.

This. You can just use .map_err(|_| the_new_error) and it's fine. (Or you can use .or(Err(the_new_error)), or ...)

The nice thing about the closure versions is that you can't accidentally run expensive code in the happy path, if it changes from a simple literal to something more complicated.

See https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call.

2 Likes

I think the closest match is or, but you'll need to construct an Err(val) instead of just providing the val. Here are the examples from the docs:

let x: Result<u32, &str> = Ok(2);
let y: Result<u32, &str> = Err("late error");
assert_eq!(x.or(y), Ok(2));

let x: Result<u32, &str> = Err("early error");
let y: Result<u32, &str> = Ok(2);
assert_eq!(x.or(y), Ok(2));

let x: Result<u32, &str> = Err("not a 2");
let y: Result<u32, &str> = Err("late error");
assert_eq!(x.or(y), Err("late error"));

let x: Result<u32, &str> = Ok(2);
let y: Result<u32, &str> = Ok(100);
assert_eq!(x.or(y), Ok(2));
1 Like

This makes sense, ideally, the Ok branch should be used more than the Err branch, so gating the latter behind a function call should be fine.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.