use std::path::{Path, PathBuf};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum Input {
File(PathBuf),
#[default]
Stdin,
}
impl Input {
#[must_use]
pub fn from_path(path: &Path) -> Self {
if path.as_os_str() == "-" {
Self::Stdin
} else {
Self::File(path.to_path_buf())
}
}
#[must_use]
pub fn from_option(path: Option<&Path>) -> Self {
path.map_or(Self::Stdin, Self::from_path)
}
#[must_use]
pub const fn is_stdin(&self) -> bool {
matches!(self, Self::Stdin)
}
#[must_use]
pub const fn is_file(&self) -> bool {
matches!(self, Self::File(_))
}
#[must_use]
pub fn as_path(&self) -> Option<&Path> {
match self {
Self::File(path) => Some(path),
Self::Stdin => None,
}
}
}
impl std::fmt::Display for Input {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::File(path) => write!(f, "{}", path.display()),
Self::Stdin => write!(f, "<stdin>"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_path_stdin() {
let input = Input::from_path(Path::new("-"));
assert!(input.is_stdin());
assert!(!input.is_file());
assert!(input.as_path().is_none());
}
#[test]
fn from_path_file() {
let input = Input::from_path(Path::new("test.fa"));
assert!(input.is_file());
assert!(!input.is_stdin());
assert_eq!(input.as_path(), Some(Path::new("test.fa")));
}
#[test]
fn from_option_none() {
let input = Input::from_option(None);
assert!(input.is_stdin());
}
#[test]
fn from_option_some_stdin() {
let input = Input::from_option(Some(Path::new("-")));
assert!(input.is_stdin());
}
#[test]
fn from_option_some_file() {
let input = Input::from_option(Some(Path::new("test.fa")));
assert!(input.is_file());
}
#[test]
fn display_stdin() {
let input = Input::Stdin;
assert_eq!(input.to_string(), "<stdin>");
}
#[test]
fn display_file() {
let input = Input::File(PathBuf::from("genome.fa"));
assert_eq!(input.to_string(), "genome.fa");
}
#[test]
fn default_is_stdin() {
let input = Input::default();
assert!(input.is_stdin());
}
}