use clap::Parser; use futures_util::future; use hyper::server::Server; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Request, Response}; use hyper_staticfile::Static; use std::path::PathBuf; /// find rust book location // println!("rustup_dir = {rustup_dir:?}"); // Some("/home/aaron/.rustup/toolchains/nightly-2021-12-13-x86_64-unknown-linux-gnu/share/doc/rust/html") pub fn find_rustdoc() -> Option { let output = std::process::Command::new("rustup") .arg("which") .arg("rustdoc") .output() .unwrap(); if output.status.success() { Some(PathBuf::from(String::from_utf8(output.stdout).unwrap())) } else { None } .and_then(|rustdoc| { Some( rustdoc .parent()? .parent()? .join("share") .join("doc") .join("rust") .join("html"), ) }) } /// request handler /// async fn handle_request( req: Request, static_: Static, ) -> Result, std::io::Error> { static_.clone().serve(req).await } /// serve rust book on pub async fn serve_rustbook(addr: &std::net::SocketAddr) -> Result<(), anyhow::Error> { let rustdoc_dir = find_rustdoc().unwrap(); Ok(serve_dir(addr, &rustdoc_dir).await?) } /// serve directory on pub async fn serve_dir(addr: &std::net::SocketAddr, dir: &PathBuf) -> Result<(), anyhow::Error> { let handler = make_service_fn(|_| { let dir = Static::new(dir.clone()); future::ok::<_, hyper::Error>(service_fn(move |req| handle_request(req, dir.clone()))) }); Ok(Server::bind(addr).serve(handler).await?) }