clippy and rustfmt anoyances

This commit is contained in:
Дамјан Георгиевски 2019-09-21 16:32:15 +02:00
parent c68cf3a3e8
commit da69d3de6f
3 changed files with 103 additions and 54 deletions

View file

@ -3,28 +3,34 @@ mod web;
fn main() -> std::io::Result<()> {
let app = clap::App::new(clap::crate_name!())
.author(clap::crate_authors!("\n"))
.version(clap::crate_version!())
.about(clap::crate_description!())
.arg(clap::Arg::with_name("chdir")
.short("w")
.long("chdir")
.value_name("DIRECTORY")
.help("directory to serve")
.default_value(".")
.takes_value(true))
.arg(clap::Arg::with_name("addr")
.short("b")
.long("bind")
.value_name("ADDRESS")
.help("bind address")
.default_value("0.0.0.0")
.takes_value(true))
.arg(clap::Arg::with_name("port")
.value_name("PORT")
.help("Specify alternate port")
.default_value("8000")
.index(1));
.author(clap::crate_authors!("\n"))
.version(clap::crate_version!())
.about(clap::crate_description!())
.arg(
clap::Arg::with_name("chdir")
.short("w")
.long("chdir")
.value_name("DIRECTORY")
.help("directory to serve")
.default_value(".")
.takes_value(true),
)
.arg(
clap::Arg::with_name("addr")
.short("b")
.long("bind")
.value_name("ADDRESS")
.help("bind address")
.default_value("0.0.0.0")
.takes_value(true),
)
.arg(
clap::Arg::with_name("port")
.value_name("PORT")
.help("Specify alternate port")
.default_value("8000")
.index(1),
);
let matches = app.get_matches();
let chdir = matches.value_of("chdir").unwrap(); // these shouldn't panic ever, since all have default_value
@ -32,7 +38,10 @@ fn main() -> std::io::Result<()> {
let port = matches.value_of("port").unwrap();
let bind_addr = format!("{}:{}", addr, port);
std::env::set_var("RUST_LOG", std::env::var("RUST_LOG").unwrap_or("info".to_string()));
std::env::set_var(
"RUST_LOG",
std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string()),
);
env_logger::init();
let root = std::path::PathBuf::from(chdir).canonicalize()?;

View file

@ -1,12 +1,11 @@
use bytes;
use futures;
use futures::Sink;
use bytes;
use tar;
use std::thread;
use std::path::PathBuf;
use std::io;
use std::path::PathBuf;
use std::thread;
/*
* TODO:
@ -17,7 +16,6 @@ type Stream = futures::sync::mpsc::Receiver<bytes::Bytes>;
type Sender = futures::sync::mpsc::Sender<bytes::Bytes>;
type BlockingSender = futures::sink::Wait<Sender>;
pub fn stream_tar_in_thread(path: PathBuf) -> Stream {
let (writer, stream) = StreamWriter::new(64);
@ -27,32 +25,34 @@ pub fn stream_tar_in_thread(path: PathBuf) -> Stream {
a.mode(tar::HeaderMode::Deterministic);
a.append_dir_all(last_path_component, &path)
.unwrap_or_else(|e| println!("{}", e));
a.finish()
.unwrap_or_else(|e| println!("{}", e));
a.finish().unwrap_or_else(|e| println!("{}", e));
});
stream
}
struct StreamWriter {
tx: BlockingSender
tx: BlockingSender,
}
impl StreamWriter {
fn new(size: usize) -> (Self, Stream) {
let (tx, rx) = futures::sync::mpsc::channel(size);
let tx = tx.wait();
(StreamWriter{tx:tx}, rx)
(StreamWriter { tx }, rx)
}
}
impl io::Write for StreamWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.tx.send(bytes::Bytes::from(buf))
self.tx
.send(bytes::Bytes::from(buf))
.map(|_| buf.len())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
fn flush(&mut self) -> io::Result<()> {
self.tx.flush().map_err(|e| io::Error::new(io::ErrorKind::Other, e))
self.tx
.flush()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
}

View file

@ -1,6 +1,6 @@
use actix_web::{App, middleware, error, HttpServer, HttpRequest, HttpResponse, Responder, web};
use actix_web::dev::ServiceResponse;
use actix_files as fs;
use actix_web::dev::ServiceResponse;
use actix_web::{error, middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use futures::Stream;
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use v_htmlescape::escape as escape_html_entity;
@ -10,7 +10,6 @@ use crate::threaded_archiver;
use std::fmt::Write;
use std::path::PathBuf;
pub fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> {
let root = root.clone();
HttpServer::new(move || {
@ -32,49 +31,88 @@ pub fn run(bind_addr: &str, root: &PathBuf) -> std::io::Result<()> {
.run()
}
fn handle_directory<'a, 'b>(
dir: &'a fs::Directory,
req: &'b HttpRequest,
fn handle_directory(
dir: &fs::Directory,
req: &HttpRequest,
) -> Result<ServiceResponse, std::io::Error> {
let rd = std::fs::read_dir(&dir.path)?;
fn optimistic_is_dir(entry: &std::fs::DirEntry) -> bool {
// consider it non directory if metadata reading fails, better than an unwrap() panic
entry.metadata().map(|m| m.file_type().is_dir()).unwrap_or(false)
entry
.metadata()
.map(|m| m.file_type().is_dir())
.unwrap_or(false)
}
let mut paths : Vec<_> = rd.filter_map(|entry| if dir.is_visible(&entry) { entry.ok() } else {None}).collect();
let mut paths: Vec<_> = rd
.filter_map(|entry| {
if dir.is_visible(&entry) {
entry.ok()
} else {
None
}
})
.collect();
paths.sort_by_key(|entry| (!optimistic_is_dir(entry), entry.file_name()));
let tar_url = req.path().trim_end_matches('/'); // this is already encoded
let mut body = String::new();
writeln!(body, "<h1>Index of {}</h1>", req.path()).unwrap(); // FIXME: decode from url, escape for html
writeln!(body, r#"<small>[<a href="{}.tar">.tar</a> of whole directory]</small>"#, tar_url).unwrap();
writeln!(
body,
r#"<small>[<a href="{}.tar">.tar</a> of whole directory]</small>"#,
tar_url
)
.unwrap();
writeln!(body, "<table>").unwrap();
writeln!(body, "<tr><td>📁 <a href='../'>../</a></td><td>Size</td></tr>").unwrap();
writeln!(
body,
"<tr><td>📁 <a href='../'>../</a></td><td>Size</td></tr>"
)
.unwrap();
for entry in paths {
let meta = entry.metadata()?;
let file_url = utf8_percent_encode(&entry.file_name().to_string_lossy(), NON_ALPHANUMERIC).to_string();
let file_url =
utf8_percent_encode(&entry.file_name().to_string_lossy(), NON_ALPHANUMERIC).to_string();
let file_name = escape_html_entity(&entry.file_name().to_string_lossy()).to_string();
let size = meta.len();
write!(body, "<tr>").unwrap();
if meta.file_type().is_dir() {
writeln!(body, r#"<td>📂 <a href="{}/">{}/</a></td>"#, file_url, file_name).unwrap();
write!(body, r#" <td><small>[<a href="{}.tar">.tar</a>]</small></td>"#, file_url).unwrap();
writeln!(
body,
r#"<td>📂 <a href="{}/">{}/</a></td>"#,
file_url, file_name
)
.unwrap();
write!(
body,
r#" <td><small>[<a href="{}.tar">.tar</a>]</small></td>"#,
file_url
)
.unwrap();
} else {
writeln!(body, r#"<td>🗎 <a href="{}">{}</a></td>"#, file_url, file_name).unwrap();
writeln!(
body,
r#"<td>🗎 <a href="{}">{}</a></td>"#,
file_url, file_name
)
.unwrap();
write!(body, " <td>{}</td>", size).unwrap();
}
writeln!(body, "</tr>").unwrap();
}
writeln!(body, "</table>").unwrap();
writeln!(body, r#"<footer><a href="{}">{} {}</a></footer>"#,
env!("CARGO_PKG_HOMEPAGE"), env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")).unwrap();
writeln!(
body,
r#"<footer><a href="{}">{} {}</a></footer>"#,
env!("CARGO_PKG_HOMEPAGE"),
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
)
.unwrap();
let mut html = String::new();
writeln!(html, "<!DOCTYPE html>").unwrap();
@ -85,7 +123,9 @@ fn handle_directory<'a, 'b>(
writeln!(html, "<body>\n{}</body>", body).unwrap();
writeln!(html, "</html>").unwrap();
let resp = HttpResponse::Ok().content_type("text/html; charset=utf-8").body(html);
let resp = HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(html);
Ok(ServiceResponse::new(req.clone(), resp))
}