I keep running into the situation where I need to convert a Result<A,E>
into Result<B,E>
with A
implementing Into<B>
.
The only way to achieve that that I found so far is via map(into)
.
Is there no Result::map_into()
or similar? If no, should there be?
/// Library code //////////////////////////////////
struct A(i32);
#[derive(Debug)]
struct B(i32);
impl From<A> for B {
fn from(a: A) -> Self {
Self(a.0)
}
}
type MyError = Box<dyn std::error::Error>;
fn compute_thing() -> Result<A, MyError> {
Ok(A(42))
}
/// My code //////////////////////////////////////
fn do_computation() -> Result<B, MyError> {
// There must be a better way to do this than with `map(into)`
compute_thing().map(A::into)
}
fn main() {
println!("{:?}", do_computation());
}
Proof of concept that this could be done very easily:
/// Library code /////////////////////////////////////////////////////////////
struct A(i32);
#[derive(Debug)]
struct B(i32);
impl From<A> for B {
fn from(a: A) -> Self {
Self(a.0)
}
}
type MyError = Box<dyn std::error::Error>;
fn compute_thing() -> Result<A, MyError> {
Ok(A(42))
}
/// Implementatoin of map_into ///////////////////////////////////////////////
trait MapInto<T> {
fn map_into(self) -> T;
}
impl<In, Out, E> MapInto<Result<Out, E>> for Result<In, E>
where
Out: std::convert::From<In>,
{
fn map_into(self) -> Result<Out, E> {
self.map(|s| s.into())
}
}
/// My code //////////////////////////////////////////////////////////////////
fn do_computation() -> Result<B, MyError> {
// There must be a better way to do this than with `map(into)`
compute_thing().map_into()
}
fn main() {
println!("{:?}", do_computation());
}
Functions that I personally think would be helpful:
Result::map_into()
Result::map_err_into()
Option::map_into()
Or even better:
impl From<Option<T>> for Option<U> where U: From<T>
impl From<Result<T0, E>> for Result<T1,E> where T1: From<T0>
impl From<Result<T, E0>> for Result<T,E1> where E1: From<E0>
Or similar.