Better command line parsing, version, usage
Also tests for same
This commit is contained in:
parent
52fe5523b2
commit
fc144162b9
3 changed files with 132 additions and 11 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -256,6 +256,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"home",
|
"home",
|
||||||
|
"indoc",
|
||||||
"log",
|
"log",
|
||||||
"open",
|
"open",
|
||||||
"procfs",
|
"procfs",
|
||||||
|
|
@ -328,6 +329,12 @@ dependencies = [
|
||||||
"cxx-build",
|
"cxx-build",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indoc"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da2d6f23ffea9d7e76c53eee25dfb67bcd8fde7f1198b0855350698c9f07c780"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ anyhow = "1.0"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
crossterm = { version = "0.25", features = ["event-stream"] }
|
crossterm = { version = "0.25", features = ["event-stream"] }
|
||||||
home = "0.5.4"
|
home = "0.5.4"
|
||||||
|
indoc = "1"
|
||||||
log = { version = "0.4", features = ["std"] }
|
log = { version = "0.4", features = ["std"] }
|
||||||
open = "3"
|
open = "3"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
|
||||||
133
src/main.rs
133
src/main.rs
|
|
@ -1,19 +1,132 @@
|
||||||
// TODO: An actual proper UI.
|
// TODO: An actual proper command line parsing
|
||||||
|
use indoc::indoc;
|
||||||
|
|
||||||
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
fn usage() {
|
||||||
|
println!(indoc! {"
|
||||||
|
usage: fwd [--version] (<server> | browse <url>)
|
||||||
|
|
||||||
|
To connect a client to a server that has an `fwd` installed in its path, run
|
||||||
|
`fwd <server>` on the client, where <server> is the name of the server to
|
||||||
|
connect to.
|
||||||
|
|
||||||
|
On a server that already has a client connected to it you can use `fwd browse
|
||||||
|
<url>` to open `<url>` in the default browser of the client.
|
||||||
|
"});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Args {
|
||||||
|
Help,
|
||||||
|
Version,
|
||||||
|
Server,
|
||||||
|
Client(String),
|
||||||
|
Browse(String),
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_args(args: Vec<String>) -> Args {
|
||||||
|
// Look for help; allow it to come anywhere because sometimes you just
|
||||||
|
// want to jam it on the end of an existing command line.
|
||||||
|
for arg in &args {
|
||||||
|
if arg == "--help" || arg == "-?" || arg == "-h" {
|
||||||
|
return Args::Help;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No help, parse for reals.
|
||||||
|
if args.len() >= 2 && args[1] == "--version" {
|
||||||
|
Args::Version
|
||||||
|
} else if args.len() == 2 && &args[1] == "--server" {
|
||||||
|
Args::Server
|
||||||
|
} else if args.len() == 3 && args[1] == "browse" {
|
||||||
|
Args::Browse(args[2].to_string())
|
||||||
|
} else {
|
||||||
|
if args.len() != 2 {
|
||||||
|
Args::Error
|
||||||
|
} else {
|
||||||
|
Args::Client(args[1].to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let args: Vec<String> = std::env::args().collect();
|
match parse_args(std::env::args().collect()) {
|
||||||
|
Args::Help => {
|
||||||
if args.len() == 2 && &args[1] == "--server" {
|
usage();
|
||||||
|
}
|
||||||
|
Args::Version => {
|
||||||
|
println!("fwd {VERSION}");
|
||||||
|
}
|
||||||
|
Args::Server => {
|
||||||
fwd::run_server().await;
|
fwd::run_server().await;
|
||||||
} else if args.len() == 3 && args[1] == "browse" {
|
}
|
||||||
fwd::browse_url(&args[2]).await;
|
Args::Browse(url) => {
|
||||||
} else {
|
fwd::browse_url(&url).await;
|
||||||
if args.len() < 2 {
|
}
|
||||||
eprintln!("Usage: fwd <server>");
|
Args::Client(server) => {
|
||||||
|
fwd::run_client(&server).await;
|
||||||
|
}
|
||||||
|
Args::Error => {
|
||||||
|
usage();
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fwd::run_client(&args[1]).await;
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use assert_matches::assert_matches;
|
||||||
|
|
||||||
|
// Goldarn it.
|
||||||
|
fn args(x: &[&str]) -> Vec<String> {
|
||||||
|
let mut vec: Vec<String> =
|
||||||
|
x.into_iter().map(|a| a.to_string()).collect();
|
||||||
|
vec.insert(0, "fwd".to_string());
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_arg_parse {
|
||||||
|
( $x:expr, $p:pat ) => {
|
||||||
|
assert_matches!(parse_args(args($x)), $p)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn help() {
|
||||||
|
assert_arg_parse!(&["--help"], Args::Help);
|
||||||
|
assert_arg_parse!(&["browse", "--help"], Args::Help);
|
||||||
|
assert_arg_parse!(&["foo.com", "--help"], Args::Help);
|
||||||
|
assert_arg_parse!(&["--help", "foo.com"], Args::Help);
|
||||||
|
assert_arg_parse!(&["browse", "-?"], Args::Help);
|
||||||
|
assert_arg_parse!(&["foo.com", "-h"], Args::Help);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn errors() {
|
||||||
|
assert_arg_parse!(&[], Args::Error);
|
||||||
|
assert_arg_parse!(&["browse", "google.com", "what"], Args::Error);
|
||||||
|
assert_arg_parse!(&["a", "b"], Args::Error);
|
||||||
|
assert_arg_parse!(&["--server", "something"], Args::Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn client() {
|
||||||
|
assert_arg_parse!(&["foo.com"], Args::Client(_));
|
||||||
|
assert_arg_parse!(&["a"], Args::Client(_));
|
||||||
|
assert_arg_parse!(&["browse"], Args::Client(_));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn server() {
|
||||||
|
assert_arg_parse!(&["--server"], Args::Server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn browse() {
|
||||||
|
assert_arg_parse!(&["browse", "google.com"], Args::Browse(_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue