0
votes

given a std::time::SystemTime in the past, I'd like to manipulate elapsed() in a method via:

fn render(&self) -> Result<(), String> {
...
let elapsed = self.start.elapsed()?.as_secs();
...
}

however, ? operator wants to convert std::time::SystemTimeError to String, and From for std::time::SystemTimeError doesn't provide such a conversion. Unfortunately, it doesn't seem like you can:

impl From<std::time::SystemTimeError> for std::time::SystemTimeError {
fn from(e: std::time::SystemTimeError) -> Self { ... }
}

I really don't want to have to add match to handle this, nor do I simply want to unwrap() without error checking. I could define a fn that wraps the match and returns a Result<std::time::Duration, String>, but that seems misguided. What am I missing?

Update: After much futzing around with snafu; yes, I really like it. Adding the SystemTimeError was a breeze. However, it took me a while to sort out how to deal with the errors returned from the other crated (where they are Result<(), String>. I finally found that I just needed to add a GenericError to my Error enum and then implement std::convert::From for Error to create the GenericError.

1
You probably better make the result type more generic rather than trying to convert error into String. - Kitsu
Error type generally implement display and everything that implement display implement ToString. - Stargateur
I used Result<(), String> due to a using a crate that implements many methods that return Result<(), String> (calls to crate not shown). Should I introduce a new trait here or generic that handles String and std::time::SystemTimeError, and what do I do about the next case I run into? It seems like From<T> was designed to handle this and I'm just missing something -- I'm a rust noob. - Bruce
if you want clean error handle I advice you crates.io/crates/snafu - Stargateur
snafu does seem to offer a solution. I'm concerned about the weightiness of it -- but its likely that's me, just not mind-melding with rust yet. - Bruce

1 Answers

0
votes

Most people (myself included) will advise against using String with Result, as you can lose Error information that way. However I dont think thats the whole story. For your example, you can use the venerable map_err:

let elapsed = self.start.elapsed().map_err(|e|
   e.to_string()
)?;

as detailed by Andrew Gallant. If you want to include full Error object, you can do something like this:

let elapsed = self.start.elapsed().map_err(|e|
   format!("{:?}", e)
)?;

Or, depending on the situation you might be able to avoid both Results and panics:

let elapsed = self.start.elapsed().unwrap_or_default();