Reputation: 25
I have a function in Rust that takes in two arguments and returns a Result. It is defined below as follows.
fn calculate_density(a: String, with_correction: bool) -> Result<u64, String>;
The thing is I want to modify my method signature in such a way that the return type for a successful result depends on the argument with_correction
.
For example id with_correction
is set to true I send back u64. If false I want to send a String.
I have tried to do this with a tuple where the successful result is a tuple of Options and they are set at run time depending on with_correction
fn calculate_density(a: String, with_correction: bool) -> Result<(Option<u64>, Option<String>), String>;
But this seems like an overkill. Are there better ways to achieve this?
Upvotes: 0
Views: 787
Reputation: 27356
If your output depends on a single bool
input the first thing you should consider is splitting it up into 2 functions:
fn calculate_density(a: String) -> Result<String, String> {
// do stuff
}
fn calculate_density_with_correction(a: String) -> Result<u64, String> {
calculate_density(a).map(|density| density.parse::<u64>().unwrap_or_default())
}
If you really, really want to have multiple outputs with different types you could use an enum like this:
enum Output {
WithCorrection(u64),
WithoutCorrection(String),
}
fn calculate_density(a: String, with_correction: bool) -> Result<Output, String> {
// …
let uncorrected = String::from("uncorrected_value");
if with_correction {
let corrected = correct(uncorrected);
Ok(Output::WithCorrection(corrected))
} else {
Ok(Output::WithoutCorrection(uncorrected))
}
}
or if you don't want to write a custom enum
use Either
:
use either::Either;
fn calculate_density(a: String, with_correction: bool) -> Result<Either<u64, String>, String> {
// …
let uncorrected = String::from("uncorrected_value");
if with_correction {
let corrected = correct(uncorrected);
Ok(Either::Left(corrected))
} else {
Ok(Either::Right(uncorrected))
}
}
Upvotes: 6