use std::io;
pub trait IoResultOptional<T> {
fn optional(self) -> io::Result<Option<T>>;
}
impl<T> IoResultOptional<T> for io::Result<T> {
fn optional(self) -> io::Result<Option<T>> {
match self {
Ok(value) => Ok(Some(value)),
Err(ref e) if e.kind() == io::ErrorKind::NotFound => Ok(None),
Err(e) => Err(e),
}
}
}
#[cfg(test)]
mod tests {
use crate::IoResultOptional;
use std::fs::File;
use std::io;
use std::path::Path;
#[test]
fn existing_some() {
assert!(
File::open(&Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml"))
.optional()
.unwrap()
.is_some()
)
}
#[test]
fn non_existing_none() {
assert!(
File::open(&Path::new(env!("CARGO_MANIFEST_DIR")).join("nosuch.file"))
.optional()
.unwrap()
.is_none()
)
}
#[test]
fn other_is_error() {
let result: io::Result<()> = Err(io::Error::new(io::ErrorKind::TimedOut, "too slow"));
assert_eq!(
format!("{:?}", result.optional()),
"Err(Custom { kind: TimedOut, error: StringError(\"too slow\") })",
)
}
}