use std::ffi::OsStr;
use std::io;
use std::net::{AddrParseError, IpAddr, SocketAddr};
use std::path::PathBuf;
use clap::{AppSettings, Parser};
macro_rules! DEFAULT_PORT {
(int) => {
3000
};
(str) => {
"3000"
};
}
fn addr_from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
match s.parse::<u16>() {
Ok(port) => return Ok(SocketAddr::from(([127, 0, 0, 1], port))),
Err(_) => {}
}
match s.parse::<IpAddr>() {
Ok(host) => return Ok(SocketAddr::from((host, DEFAULT_PORT!(int)))),
Err(_) => {}
}
s.parse::<SocketAddr>()
}
fn parse_canonicalize_dir(s: &OsStr) -> Result<PathBuf, io::Error> {
PathBuf::from(s).canonicalize()
}
#[derive(Debug, Parser)]
#[clap(name = "Zy")]
#[clap(about, version, setting = AppSettings::DeriveDisplayOrder)]
pub struct Args {
#[clap(default_value = ".", parse(try_from_os_str = parse_canonicalize_dir))]
pub dir: PathBuf,
#[clap(short, long, value_name = "URI", multiple_occurrences = true)]
#[clap(verbatim_doc_comment, parse(try_from_str = addr_from_str))]
#[clap(default_value = concat!("127.0.0.1:", DEFAULT_PORT!(str)))]
pub listen: Vec<SocketAddr>,
#[clap(short, long)]
pub spa: bool,
#[clap(short, long, value_name = "FILE", default_value = "index.html")]
pub index: String,
#[clap(long = "404", value_name = "FILE", default_value = "404.html")]
pub not_found: String,
#[clap(short, long, value_name = "SECS", default_value_t = 3600)]
pub cache: u32,
#[clap(long)]
pub no_cors: bool,
#[clap(short, long)]
pub all: bool,
#[clap(short, long)]
pub follow_links: bool,
#[clap(short, long)]
pub verbose: bool,
#[clap(short = 'x', long)]
pub confirm_exit: bool,
}