use std::{ net::{SocketAddr, ToSocketAddrs}, path::PathBuf, }; use structopt::{self, StructOpt}; fn to_socket_addr(src: &str) -> Result { use std::io::{Error, ErrorKind}; src.to_socket_addrs()?.next().ok_or(Error::new( ErrorKind::Other, "could not get a valid socket address", )) } pub enum TargetOs { Linux, Windows, } impl std::str::FromStr for TargetOs { type Err = &'static str; fn from_str(input: &str) -> Result { match input { "linux" => Ok(Self::Linux), "windows" => Ok(Self::Windows), _ => Err("could not parse target operating system"), } } } #[derive(StructOpt)] pub enum Command { Generate { #[structopt(parse(from_os_str))] name: PathBuf, #[structopt(long, short, default_value = "54248")] port: u16, #[structopt(long, short, default_value = "linux")] target: TargetOs, }, Connect { #[structopt(parse(from_os_str))] config: PathBuf, #[structopt(parse(try_from_str = to_socket_addr))] ip: SocketAddr, }, ConnectTest { #[structopt(parse(from_os_str))] config: PathBuf, #[structopt(parse(try_from_str = to_socket_addr))] ip: SocketAddr, }, } #[derive(StructOpt)] #[structopt( name = "sparse-client", about = "Client to and generator of sparse shells" )] pub struct Options { #[structopt(subcommand)] pub command: Command, }