pub type Result<T, E = Error> = core::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Command error: stdout={stdout}; stderr={stderr}")]
CommandError { stdout: String, stderr: String },
#[error("{0}")]
IoError(String),
#[error("{0}")]
TimeoutError(String),
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
Error::IoError(error.to_string())
}
}
#[cfg(feature = "tokio")]
impl From<tokio::time::error::Elapsed> for Error {
fn from(error: tokio::time::error::Elapsed) -> Self {
Error::TimeoutError(error.to_string())
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_from_io_error() {
let io_error = std::io::Error::other("test");
let error = Error::from(io_error);
assert_eq!(error.to_string(), "test");
}
#[cfg(feature = "tokio")]
#[tokio::test]
async fn test_from_elapsed_error() {
let result = tokio::time::timeout(std::time::Duration::from_nanos(1), async {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
})
.await;
assert!(result.is_err());
if let Err(elapsed_error) = result {
let error = Error::from(elapsed_error);
assert_eq!(error.to_string(), "deadline has elapsed");
}
}
}