#![deny(missing_debug_implementations)]
use cfg_if::cfg_if;
use twiggy_traits as traits;
cfg_if! {
if #[cfg(feature = "cli")] {
include!(concat!(env!("OUT_DIR"), "/cli.rs"));
} else if #[cfg(feature = "wasm")] {
use wasm_bindgen::prelude::*;
include!(concat!(env!("OUT_DIR"), "/wasm.rs"));
} else {
compile_error!("Must enable one of either `cli` or `wasm` features");
}
}
use std::u32;
cfg_if! {
if #[cfg(feature = "cli")] {
use std::fs;
use std::io;
use std::path;
use std::str::FromStr;
pub trait CommonCliOptions {
fn input(&self) -> &path::Path;
fn parse_mode(&self) -> traits::ParseMode;
fn output_destination(&self) -> &OutputDestination;
fn output_format(&self) -> traits::OutputFormat;
}
impl CommonCliOptions for Options {
fn input(&self) -> &path::Path {
match *self {
Options::Top(ref top) => top.input(),
Options::Dominators(ref doms) => doms.input(),
Options::Paths(ref paths) => paths.input(),
Options::Monos(ref monos) => monos.input(),
Options::Diff(ref diff) => diff.input(),
Options::Garbage(ref garbo) => garbo.input(),
}
}
fn parse_mode(&self) -> traits::ParseMode {
match *self {
Options::Top(ref top) => top.parse_mode(),
Options::Dominators(ref doms) => doms.parse_mode(),
Options::Paths(ref paths) => paths.parse_mode(),
Options::Monos(ref monos) => monos.parse_mode(),
Options::Diff(ref diff) => diff.parse_mode(),
Options::Garbage(ref garbo) => garbo.parse_mode(),
}
}
fn output_destination(&self) -> &OutputDestination {
match *self {
Options::Top(ref top) => top.output_destination(),
Options::Dominators(ref doms) => doms.output_destination(),
Options::Paths(ref paths) => paths.output_destination(),
Options::Monos(ref monos) => monos.output_destination(),
Options::Diff(ref diff) => diff.output_destination(),
Options::Garbage(ref garbo) => garbo.output_destination(),
}
}
fn output_format(&self) -> traits::OutputFormat {
match *self {
Options::Top(ref top) => top.output_format(),
Options::Dominators(ref doms) => doms.output_format(),
Options::Paths(ref paths) => paths.output_format(),
Options::Monos(ref monos) => monos.output_format(),
Options::Diff(ref diff) => diff.output_format(),
Options::Garbage(ref garbo) => garbo.output_format(),
}
}
}
impl CommonCliOptions for Top {
fn input(&self) -> &path::Path {
&self.input
}
fn parse_mode(&self) -> traits::ParseMode {
self.parse_mode
}
fn output_destination(&self) -> &OutputDestination {
&self.output_destination
}
fn output_format(&self) -> traits::OutputFormat {
self.output_format
}
}
impl CommonCliOptions for Dominators {
fn input(&self) -> &path::Path {
&self.input
}
fn parse_mode(&self) -> traits::ParseMode {
self.parse_mode
}
fn output_destination(&self) -> &OutputDestination {
&self.output_destination
}
fn output_format(&self) -> traits::OutputFormat {
self.output_format
}
}
impl CommonCliOptions for Paths {
fn input(&self) -> &path::Path {
&self.input
}
fn parse_mode(&self) -> traits::ParseMode {
self.parse_mode
}
fn output_destination(&self) -> &OutputDestination {
&self.output_destination
}
fn output_format(&self) -> traits::OutputFormat {
self.output_format
}
}
impl CommonCliOptions for Monos {
fn input(&self) -> &path::Path {
&self.input
}
fn parse_mode(&self) -> traits::ParseMode {
self.parse_mode
}
fn output_destination(&self) -> &OutputDestination {
&self.output_destination
}
fn output_format(&self) -> traits::OutputFormat {
self.output_format
}
}
impl CommonCliOptions for Diff {
fn input(&self) -> &path::Path {
&self.old_input
}
fn parse_mode(&self) -> traits::ParseMode {
self.parse_mode
}
fn output_destination(&self) -> &OutputDestination {
&self.output_destination
}
fn output_format(&self) -> traits::OutputFormat {
self.output_format
}
}
impl Diff {
pub fn new_input(&self) -> &path::Path {
&self.new_input
}
}
impl CommonCliOptions for Garbage {
fn input(&self) -> &path::Path {
&self.input
}
fn parse_mode(&self) -> traits::ParseMode {
self.parse_mode
}
fn output_destination(&self) -> &OutputDestination {
&self.output_destination
}
fn output_format(&self) -> traits::OutputFormat {
self.output_format
}
}
#[derive(Clone, Debug)]
pub enum OutputDestination {
Stdout,
Path(path::PathBuf),
}
impl Default for OutputDestination {
fn default() -> OutputDestination {
OutputDestination::Stdout
}
}
impl FromStr for OutputDestination {
type Err = traits::Error;
fn from_str(s: &str) -> Result<Self, traits::Error> {
if s == "-" {
Ok(OutputDestination::Stdout)
} else {
let path = path::PathBuf::from(s.to_string());
Ok(OutputDestination::Path(path))
}
}
}
impl OutputDestination {
pub fn open(&self) -> Result<Box<dyn io::Write>, traits::Error> {
Ok(match *self {
OutputDestination::Path(ref path) => {
Box::new(io::BufWriter::new(fs::File::create(path)?)) as Box<_>
}
OutputDestination::Stdout => Box::new(io::stdout()) as Box<_>,
})
}
}
}
}