use std::path::{Path, PathBuf};
use std::str::FromStr;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "mdsh")]
pub struct Opt {
#[structopt(
short = "i",
long = "inputs",
alias = "input",
default_value = "./README.md"
)]
pub inputs: Vec<FileArg>,
#[structopt(short = "o", long = "output")]
pub output: Option<FileArg>,
#[structopt(long = "work_dir", parse(from_os_str))]
pub work_dir: Option<PathBuf>,
#[structopt(long = "frozen", conflicts_with = "clean")]
pub frozen: bool,
#[structopt(long = "clean")]
pub clean: bool,
}
#[derive(Debug, Clone)]
pub enum FileArg {
StdHandle,
File(PathBuf),
}
impl FileArg {
pub fn parent(&self) -> Option<Parent> {
match self {
FileArg::StdHandle => Some(Parent::current_dir()),
FileArg::File(buf) => Parent::of(buf),
}
}
pub fn from_str_unsafe(s: &str) -> Self {
FileArg::File(PathBuf::from(s))
}
}
impl FromStr for FileArg {
type Err = std::string::ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"-" => Ok(FileArg::StdHandle),
p => Ok(FileArg::File(PathBuf::from(p))),
}
}
}
#[derive(Debug, Clone)]
pub struct Parent(PathBuf);
impl Parent {
pub fn of(p: &Path) -> Option<Self> {
let prnt = p.parent()?;
if prnt.as_os_str().is_empty() {
Some(Self::current_dir())
} else {
Some(Parent(prnt.to_path_buf()))
}
}
pub fn current_dir() -> Self {
Parent(
std::env::current_dir().expect(
"fatal: current working directory not accessible and `--work_dir` not given",
),
)
}
pub fn from_parent_path_buf(buf: PathBuf) -> Self {
Parent(buf)
}
pub fn as_path_buf(&self) -> &PathBuf {
&self.0
}
}