use clap::Parser;
use std::path::PathBuf;
mod lib;
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
enum Executable {
#[clap(name = "docs")]
Docs(Options),
}
#[derive(Parser)]
struct Options {
#[clap(long, env = "HOST", default_value = "127.0.0.1")]
host: String,
#[clap(short = 'p', long, env = "PORT", default_value = "8080")]
port: String,
#[clap(short = 'd', long, env = "DIR")]
dir: Option<PathBuf>,
#[clap(short = 'c', long, default_value = "Cargo.toml")]
manifest_path: String,
#[clap(short = 'w', long)]
watch: bool,
#[clap(short = 'o', long)]
open: bool,
#[clap(short = 'b', long)]
book: bool,
extra_args: Vec<String>,
}
impl Options {
fn host(&self) -> String {
self.host.clone()
}
fn port(&self) -> String {
self.port.clone()
}
fn hostport(&self) -> String {
format!("{}:{}", self.host(), self.port())
}
fn addr(&self) -> std::net::SocketAddr {
self.hostport().parse().unwrap()
}
async fn run(&self) -> Result<(), anyhow::Error> {
let hostport = self.hostport();
Ok(if let Some(dir) = self.dir.clone() {
let content = dir.into_os_string().into_string().unwrap();
println!("Serving {content} on http://{hostport}");
lib::serve_dir(&self.addr(), &self.dir.clone().unwrap()).await?
} else if self.book {
let content = "rust doc";
println!("Serving {content} on http://{hostport}");
lib::serve_rust_doc(&self.addr()).await?
} else {
let content = "crate doc";
lib::run_cargo_doc(&self.extra_args);
println!("Serving {content} on http://{hostport}");
lib::serve_crate_doc(&self.manifest_path(), &self.addr()).await?
})
}
fn manifest_path(&self) -> PathBuf {
let mut manifest_path = PathBuf::from(&self.manifest_path);
if !manifest_path.is_absolute() {
manifest_path = std::env::current_dir().unwrap().join(manifest_path);
}
manifest_path
}
}
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
Ok(match Executable::parse() {
Executable::Docs(options) => {
options.run().await?;
}
})
}