From 066535edaefa2c1f34531d8be5ad280d914a9edd Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Tue, 12 Feb 2019 20:20:57 +0100 Subject: Split project into multiple files --- src/args.rs | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 src/args.rs (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..a3a440e --- /dev/null +++ b/src/args.rs @@ -0,0 +1,167 @@ +use crate::auth; +use crate::config; +use crate::listing; +use clap::{crate_authors, crate_description, crate_name, crate_version}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::path::PathBuf; + +const ROUTE_ALPHABET: [char; 16] = [ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', +]; + +fn is_valid_path(path: String) -> Result<(), String> { + let path_to_check = PathBuf::from(path); + if path_to_check.is_file() || path_to_check.is_dir() { + return Ok(()); + } + Err(String::from( + "Path either doesn't exist or is not a regular file or a directory", + )) +} + +fn is_valid_port(port: String) -> Result<(), String> { + port.parse::() + .and(Ok(())) + .or_else(|e| Err(e.to_string())) +} + +fn is_valid_interface(interface: String) -> Result<(), String> { + interface + .parse::() + .and(Ok(())) + .or_else(|e| Err(e.to_string())) +} + +fn is_valid_auth(auth: String) -> Result<(), String> { + auth.find(':') + .ok_or_else(|| "Correct format is username:password".to_owned()) + .map(|_| ()) +} + +pub fn parse_args() -> config::MiniserveConfig { + use clap::{App, AppSettings, Arg}; + + let matches = App::new(crate_name!()) + .version(crate_version!()) + .author(crate_authors!()) + .about(crate_description!()) + .global_setting(AppSettings::ColoredHelp) + .arg( + Arg::with_name("verbose") + .short("v") + .long("verbose") + .help("Be verbose, includes emitting access logs"), + ) + .arg( + Arg::with_name("PATH") + .required(false) + .validator(is_valid_path) + .help("Which path to serve"), + ) + .arg( + Arg::with_name("port") + .short("p") + .long("port") + .help("Port to use") + .validator(is_valid_port) + .required(false) + .default_value("8080") + .takes_value(true), + ) + .arg( + Arg::with_name("interfaces") + .short("i") + .long("if") + .help("Interface to listen on") + .validator(is_valid_interface) + .required(false) + .takes_value(true) + .multiple(true), + ) + .arg( + Arg::with_name("auth") + .short("a") + .long("auth") + .validator(is_valid_auth) + .help("Set authentication (username:password)") + .takes_value(true), + ) + .arg( + Arg::with_name("random-route") + .long("random-route") + .help("Generate a random 6-hexdigit route"), + ) + .arg( + Arg::with_name("sort") + .short("s") + .long("sort") + .possible_values(&["natural", "alpha", "dirsfirst"]) + .default_value("natural") + .help("Sort files"), + ) + .arg( + Arg::with_name("reverse") + .long("reverse") + .help("Reverse sorting order"), + ) + .arg( + Arg::with_name("no-symlinks") + .short("P") + .long("no-symlinks") + .help("Do not follow symbolic links"), + ) + .get_matches(); + + let verbose = matches.is_present("verbose"); + let no_symlinks = matches.is_present("no-symlinks"); + let path = matches.value_of("PATH"); + let port = matches.value_of("port").unwrap().parse().unwrap(); + let interfaces = if let Some(interfaces) = matches.values_of("interfaces") { + interfaces.map(|x| x.parse().unwrap()).collect() + } else { + vec![ + IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), + IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), + ] + }; + let auth = if let Some(auth_split) = matches.value_of("auth").map(|x| x.splitn(2, ':')) { + let auth_vec = auth_split.collect::>(); + if auth_vec.len() == 2 { + Some(auth::BasicAuthParams { + username: auth_vec[0].to_owned(), + password: auth_vec[1].to_owned(), + }) + } else { + None + } + } else { + None + }; + + let random_route = if matches.is_present("random-route") { + Some(nanoid::custom(6, &ROUTE_ALPHABET)) + } else { + None + }; + + let sort_method = matches + .value_of("sort") + .unwrap() + .parse::() + .unwrap(); + + let reverse_sort = matches.is_present("reverse"); + + config::MiniserveConfig { + verbose, + path: PathBuf::from(path.unwrap_or(".")), + port, + interfaces, + auth, + path_explicitly_chosen: path.is_some(), + no_symlinks, + random_route, + sort_method, + reverse_sort, + } +} -- cgit v1.2.3 From d410b27e85ffa653a64d10bcd6b43cc5f64fe5d9 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Wed, 13 Feb 2019 18:51:51 +0100 Subject: Removed config.rs and put back actix config in main.rs --- src/args.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index a3a440e..64ff3e6 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,4 @@ use crate::auth; -use crate::config; use crate::listing; use clap::{crate_authors, crate_description, crate_name, crate_version}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; @@ -38,7 +37,7 @@ fn is_valid_auth(auth: String) -> Result<(), String> { .map(|_| ()) } -pub fn parse_args() -> config::MiniserveConfig { +pub fn parse_args() -> crate::MiniserveConfig { use clap::{App, AppSettings, Arg}; let matches = App::new(crate_name!()) @@ -152,7 +151,7 @@ pub fn parse_args() -> config::MiniserveConfig { let reverse_sort = matches.is_present("reverse"); - config::MiniserveConfig { + crate::MiniserveConfig { verbose, path: PathBuf::from(path.unwrap_or(".")), port, -- cgit v1.2.3 From 3e2c3341ee4fd540126f822ef23aa442508cf4b6 Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Wed, 13 Feb 2019 19:13:34 +0100 Subject: Added some docstrings --- src/args.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs index 64ff3e6..ae86108 100644 --- a/src/args.rs +++ b/src/args.rs @@ -4,10 +4,12 @@ use clap::{crate_authors, crate_description, crate_name, crate_version}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::path::PathBuf; +/// Possible characters for random routes const ROUTE_ALPHABET: [char; 16] = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', ]; +/// Checks wether a path is valid, i.e. it exists on the system and points to a file/directory fn is_valid_path(path: String) -> Result<(), String> { let path_to_check = PathBuf::from(path); if path_to_check.is_file() || path_to_check.is_dir() { @@ -18,12 +20,15 @@ fn is_valid_path(path: String) -> Result<(), String> { )) } +/// Checks wether a port is valid fn is_valid_port(port: String) -> Result<(), String> { port.parse::() .and(Ok(())) .or_else(|e| Err(e.to_string())) } + +/// Checks wether an interface is valid, i.e. it can be parsed into an IP address fn is_valid_interface(interface: String) -> Result<(), String> { interface .parse::() @@ -31,12 +36,14 @@ fn is_valid_interface(interface: String) -> Result<(), String> { .or_else(|e| Err(e.to_string())) } +/// Checks wether the auth string is valid, i.e. it follows the syntax username:password fn is_valid_auth(auth: String) -> Result<(), String> { auth.find(':') .ok_or_else(|| "Correct format is username:password".to_owned()) .map(|_| ()) } +/// Parses the command line arguments pub fn parse_args() -> crate::MiniserveConfig { use clap::{App, AppSettings, Arg}; -- cgit v1.2.3