use std::str::FromStr;
use super::Dest;
#[derive(Debug, Clone)]
pub struct FileOrStdout {
dest: Dest,
}
impl FileOrStdout {
pub fn is_stdout(&self) -> bool {
matches!(self.dest, Dest::Stdout)
}
pub fn is_file(&self) -> bool {
!self.is_stdout()
}
pub fn filename(&self) -> &str {
match &self.dest {
Dest::Stdout => "-",
Dest::Arg(path) => path,
}
}
pub fn into_writer(self) -> Result<impl std::io::Write, std::io::Error> {
self.dest.into_writer()
}
#[cfg(feature = "tokio")]
pub async fn into_async_writer(&self) -> std::io::Result<impl tokio::io::AsyncWrite> {
let output: std::pin::Pin<Box<dyn tokio::io::AsyncWrite + 'static>> = match &self.dest {
Dest::Stdout => Box::pin(tokio::io::stdout()),
Dest::Arg(filepath) => {
let f = tokio::fs::File::open(filepath).await?;
Box::pin(f)
}
};
Ok(output)
}
}
impl FromStr for FileOrStdout {
type Err = std::io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let dest = Dest::from_str(s)?;
Ok(Self { dest })
}
}
#[test]
fn test_source_methods() {
let val: FileOrStdout = "-".parse().unwrap();
assert!(val.is_stdout());
assert!(!val.is_file());
assert_eq!(val.filename(), "-");
let val: FileOrStdout = "/path/to/something".parse().unwrap();
assert!(val.is_file());
assert!(!val.is_stdout());
assert_eq!(val.filename(), "/path/to/something");
}