Simple parameter configuration replaced with macro expressions

This commit is contained in:
Stzx
2020-03-27 20:36:46 +08:00
committed by Y. T. CHUNG
parent c96ab84ad2
commit c391fc0fae
6 changed files with 128 additions and 495 deletions
+29 -105
View File
@@ -4,19 +4,19 @@
//! or you could specify a configuration file. The format of configuration file is defined
//! in mod `config`.
use clap::{App, Arg, ArgGroup};
use clap::{Arg, clap_app};
use futures::future::{self, Either};
use log::{error, info};
use tokio::{self, runtime::Builder};
use shadowsocks::{
acl::AccessControl,
crypto::CipherType,
plugin::PluginConfig,
run_local,
Config,
ConfigType,
crypto::CipherType,
Mode,
plugin::PluginConfig,
run_local,
ServerAddr,
ServerConfig,
};
@@ -27,102 +27,39 @@ mod monitor;
fn main() {
let available_ciphers = CipherType::available_ciphers();
let mut app = App::new("shadowsocks")
.version(shadowsocks::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls.")
.arg(
Arg::with_name("VERBOSE")
.short("v")
.multiple(true)
.help("Set the level of debug"),
let mut app = clap_app!(shadowsocks =>
(version: shadowsocks::VERSION)
(about: "A fast tunnel proxy that helps you bypass firewalls.")
(@arg VERBOSE: -v ... "Set the level of debug")
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
(@arg TCP_AND_UDP: -U conflicts_with[UDP_ONLY] "Server mode TCP_AND_UDP")
(@arg CONFIG: -c --config +takes_value "Specify config file")
(@arg LOCAL_ADDR: -b --("local-addr") +takes_value "Local address, listen only to this address if specified")
(@arg SERVER_ADDR: -s --("server-addr") +takes_value requires[PASSWORD ENCRYPT_METHOD] "Server address")
(@arg PASSWORD: -k --password +takes_value requires[SERVER_ADDR ENCRYPT_METHOD] "Password")
(@arg PLUGIN: --plugin +takes_value "Enable SIP003 plugin")
(@arg PLUGIN_OPT: --("plugin-opts") +takes_value requires[PLUGIN] "Set SIP003 plugin options")
(@arg URL: --("server-url") +takes_value "Server address in SIP002 URL")
(@group SERVER_CONFIG =>
(@attributes +required ... arg[CONFIG SERVER_ADDR URL])
)
.arg(
Arg::with_name("UDP_ONLY")
.short("u")
.help("Server mode UDP_ONLY")
.conflicts_with("TCP_AND_UDP"),
)
.arg(
Arg::with_name("TCP_AND_UDP")
.short("U")
.help("Server mode TCP_AND_UDP")
.conflicts_with("UDP_ONLY"),
)
.arg(
Arg::with_name("CONFIG")
.short("c")
.long("config")
.takes_value(true)
.help("Specify config file"),
)
.arg(
Arg::with_name("LOCAL_ADDR")
.short("b")
.long("local-addr")
.takes_value(true)
.help("Local address, listen only to this address if specified"),
)
.arg(
Arg::with_name("SERVER_ADDR")
.short("s")
.long("server-addr")
.takes_value(true)
.help("Server address")
.requires_all(&["PASSWORD", "ENCRYPT_METHOD"]),
)
.arg(
Arg::with_name("PASSWORD")
.short("k")
.long("password")
.takes_value(true)
.help("Password")
.requires_all(&["SERVER_ADDR", "ENCRYPT_METHOD"]),
(@group LOCAL_CONFIG =>
(@attributes +required ... arg[CONFIG LOCAL_ADDR])
)
(@arg NO_DELAY: --("no-delay") !takes_value "Set no-delay option for socket")
(@arg NOFILE: -n --nofile +takes_value "Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)")
(@arg ACL: --acl +takes_value "Path to ACL (Access Control List)")
);
app = app
.arg(
Arg::with_name("ENCRYPT_METHOD")
.short("m")
.long("encrypt-method")
.takes_value(true)
.possible_values(&available_ciphers)
.help("Encryption method")
.requires_all(&["SERVER_ADDR", "PASSWORD"]),
)
.arg(
Arg::with_name("PLUGIN")
.long("plugin")
.takes_value(true)
.help("Enable SIP003 plugin"),
)
.arg(
Arg::with_name("PLUGIN_OPT")
.long("plugin-opts")
.takes_value(true)
.help("Set SIP003 plugin options")
.requires("PLUGIN"),
)
.arg(
Arg::with_name("URL")
.long("server-url")
.takes_value(true)
.help("Server address in SIP002 URL"),
)
.group(
ArgGroup::with_name("SERVER_CONFIG")
.args(&["CONFIG", "SERVER_ADDR", "URL"])
.multiple(true)
.required(true),
)
.group(
ArgGroup::with_name("LOCAL_CONFIG")
.args(&["CONFIG", "LOCAL_ADDR"])
.multiple(true)
.required(true),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
.requires_all(&["SERVER_ADDR", "PASSWORD"])
.help("Encryption method"),
)
.arg(
Arg::with_name("PROTOCOL")
@@ -136,19 +73,6 @@ fn main() {
])
.help("Protocol that uses to communicates with clients"),
)
.arg(
Arg::with_name("NOFILE")
.short("n")
.long("nofile")
.takes_value(true)
.help("Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)"),
)
.arg(
Arg::with_name("ACL")
.long("acl")
.takes_value(true)
.help("Path to ACL (Access Control List)"),
)
.arg(
Arg::with_name("IPV6_FIRST")
.short("6")
+18 -66
View File
@@ -9,7 +9,7 @@
use std::net::{IpAddr, SocketAddr};
use clap::{App, Arg, ArgGroup};
use clap::{Arg, clap_app};
use futures::future::{self, Either};
use log::{error, info};
use tokio::{self, runtime::Builder};
@@ -29,41 +29,24 @@ mod logging;
mod monitor;
fn main() {
let matches = App::new("shadowsocks")
.version(shadowsocks::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls.")
.arg(
Arg::with_name("VERBOSE")
.short("v")
.multiple(true)
.help("Set the level of debug"),
)
.arg(
Arg::with_name("UDP_ONLY")
.short("u")
.help("Server mode UDP_ONLY")
.conflicts_with("TCP_AND_UDP"),
)
.arg(
Arg::with_name("TCP_AND_UDP")
.short("U")
.help("Server mode TCP_AND_UDP")
.conflicts_with("UDP_ONLY"),
)
.arg(
Arg::with_name("CONFIG")
.short("c")
.long("config")
.takes_value(true)
.help("Specify config file"),
)
.arg(
Arg::with_name("BIND_ADDR")
.short("b")
.long("bind-addr")
.takes_value(true)
.help("Bind address, outbound socket will bind this address"),
let app = clap_app!(shadowsocks =>
(version: shadowsocks::VERSION)
(about: "A fast tunnel proxy that helps you bypass firewalls.")
(@arg VERBOSE: -v ... "Set the level of debug")
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
(@arg TCP_AND_UDP: -U conflicts_with[UDP_ONLY] "Server mode TCP_AND_UDP")
(@arg CONFIG: -c --config +takes_value "Specify config file")
(@arg BIND_ADDR: -b --("bind-addr") +takes_value "Bind address, outbound socket will bind this address")
(@arg NO_DELAY: --("no-delay") !takes_value "Set no-delay option for socket")
(@arg MANAGER_ADDRESS: --("manager-address") +takes_value "ShadowSocks Manager (ssmgr) address, could be \"IP:Port\", \"Domain:Port\" or \"/path/to/unix.sock\"")
(@group MANAGER_CONFIG =>
(@attributes +required ... arg[CONFIG MANAGER_ADDRESS])
)
(@arg NOFILE: -n --nofile +takes_value "Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)")
(@arg ACL: --acl +takes_value "Path to ACL (Access Control List)")
);
let matches = app
.arg(
Arg::with_name("ENCRYPT_METHOD")
.short("m")
@@ -72,37 +55,6 @@ fn main() {
.possible_values(&CipherType::available_ciphers())
.help("Encryption method"),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
)
.arg(
Arg::with_name("MANAGER_ADDRESS")
.long("manager-address")
.takes_value(true)
.help("ShadowSocks Manager (ssmgr) address, could be \"IP:Port\", \"Domain:Port\" or \"/path/to/unix.sock\""),
)
.group(
ArgGroup::with_name("MANAGER_CONFIG")
.args(&["CONFIG", "MANAGER_ADDRESS"])
.multiple(true)
.required(true)
)
.arg(
Arg::with_name("NOFILE")
.short("n")
.long("nofile")
.takes_value(true)
.help("Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)"),
)
.arg(
Arg::with_name("ACL")
.long("acl")
.takes_value(true)
.help("Path to ACL (Access Control List)"),
)
.arg(
Arg::with_name("IPV6_FIRST")
.short("6")
+24 -100
View File
@@ -4,7 +4,7 @@
//! or you could specify a configuration file. The format of configuration file is defined
//! in mod `config`.
use clap::{App, Arg, ArgGroup};
use clap::{Arg, clap_app};
use futures::future::{self, Either};
use log::{error, info};
use tokio::{self, runtime::Builder};
@@ -29,57 +29,31 @@ mod monitor;
fn main() {
let available_ciphers = CipherType::available_ciphers();
let mut app = App::new("shadowsocks")
.version(shadowsocks::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls.")
.arg(
Arg::with_name("VERBOSE")
.short("v")
.multiple(true)
.help("Set the level of debug"),
let mut app = clap_app!(shadowsocks =>
(version: shadowsocks::VERSION)
(about: "A fast tunnel proxy that helps you bypass firewalls.")
(@arg VERBOSE: -v ... "Set the level of debug")
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
(@arg TCP_AND_UDP: -U conflicts_with[UDP_ONLY] "Server mode TCP_AND_UDP")
(@arg CONFIG: -c --config +takes_value "Specify config file")
(@arg LOCAL_ADDR: -b --("local-addr") +takes_value "Local address, listen only to this address if specified")
(@arg SERVER_ADDR: -s --("server-addr") +takes_value requires[PASSWORD ENCRYPT_METHOD] "Server address")
(@arg PASSWORD: -k --password +takes_value requires[SERVER_ADDR ENCRYPT_METHOD] "Password")
(@arg PLUGIN: --plugin +takes_value "Enable SIP003 plugin")
(@arg PLUGIN_OPT: --("plugin-opts") +takes_value requires[PLUGIN] "Set SIP003 plugin options")
(@arg URL: --("server-url") +takes_value "Server address in SIP002 URL")
(@group SERVER_CONFIG =>
(@attributes +required ... arg[CONFIG SERVER_ADDR URL])
)
.arg(
Arg::with_name("UDP_ONLY")
.short("u")
.help("Server mode UDP_ONLY")
.conflicts_with("TCP_AND_UDP"),
)
.arg(
Arg::with_name("TCP_AND_UDP")
.short("U")
.help("Server mode TCP_AND_UDP")
.conflicts_with("UDP_ONLY"),
)
.arg(
Arg::with_name("CONFIG")
.short("c")
.long("config")
.takes_value(true)
.help("Specify config file"),
)
.arg(
Arg::with_name("LOCAL_ADDR")
.short("b")
.long("local-addr")
.takes_value(true)
.help("Local address, listen only to this address if specified"),
)
.arg(
Arg::with_name("SERVER_ADDR")
.short("s")
.long("server-addr")
.takes_value(true)
.help("Server address")
.requires_all(&["PASSWORD", "ENCRYPT_METHOD"]),
)
.arg(
Arg::with_name("PASSWORD")
.short("k")
.long("password")
.takes_value(true)
.help("Password")
.requires_all(&["SERVER_ADDR", "ENCRYPT_METHOD"]),
(@group LOCAL_CONFIG =>
(@attributes +required ... arg[CONFIG LOCAL_ADDR])
)
(@arg NO_DELAY: --("no-delay") !takes_value "Set no-delay option for socket")
(@arg NOFILE: -n --nofile +takes_value "Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)")
(@arg ACL: --acl +takes_value "Path to ACL (Access Control List)")
);
app = app
.arg(
Arg::with_name("ENCRYPT_METHOD")
.short("m")
@@ -89,56 +63,6 @@ fn main() {
.help("Encryption method")
.requires_all(&["SERVER_ADDR", "PASSWORD"]),
)
.arg(
Arg::with_name("PLUGIN")
.long("plugin")
.takes_value(true)
.help("Enable SIP003 plugin"),
)
.arg(
Arg::with_name("PLUGIN_OPT")
.long("plugin-opts")
.takes_value(true)
.help("Set SIP003 plugin options")
.requires("PLUGIN"),
)
.arg(
Arg::with_name("URL")
.long("server-url")
.takes_value(true)
.help("Server address in SIP002 URL"),
)
.group(
ArgGroup::with_name("SERVER_CONFIG")
.args(&["CONFIG", "SERVER_ADDR", "URL"])
.multiple(true)
.required(true),
)
.group(
ArgGroup::with_name("LOCAL_CONFIG")
.args(&["CONFIG", "LOCAL_ADDR"])
.multiple(true)
.required(true),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
)
.arg(
Arg::with_name("NOFILE")
.short("n")
.long("nofile")
.takes_value(true)
.help("Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)"),
)
.arg(
Arg::with_name("ACL")
.long("acl")
.takes_value(true)
.help("Path to ACL (Access Control List)"),
)
.arg(
Arg::with_name("IPV6_FIRST")
.short("6")
+22 -95
View File
@@ -9,7 +9,7 @@
use std::net::{IpAddr, SocketAddr};
use clap::{App, Arg, ArgGroup};
use clap::{Arg, clap_app};
use futures::future::{self, Either};
use log::{error, info};
use tokio::{self, runtime::Builder};
@@ -33,57 +33,28 @@ mod monitor;
fn main() {
let available_ciphers = CipherType::available_ciphers();
let matches = App::new("shadowsocks")
.version(shadowsocks::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls.")
.arg(
Arg::with_name("VERBOSE")
.short("v")
.multiple(true)
.help("Set the level of debug"),
)
.arg(
Arg::with_name("UDP_ONLY")
.short("u")
.help("Server mode UDP_ONLY")
.conflicts_with("TCP_AND_UDP"),
)
.arg(
Arg::with_name("TCP_AND_UDP")
.short("U")
.help("Server mode TCP_AND_UDP")
.conflicts_with("UDP_ONLY"),
)
.arg(
Arg::with_name("CONFIG")
.short("c")
.long("config")
.takes_value(true)
.help("Specify config file"),
)
.arg(
Arg::with_name("BIND_ADDR")
.short("b")
.long("bind-addr")
.takes_value(true)
.help("Bind address, outbound socket will bind this address"),
)
.arg(
Arg::with_name("SERVER_ADDR")
.short("s")
.long("server-addr")
.takes_value(true)
.help("Server address")
.requires_all(&["PASSWORD", "ENCRYPT_METHOD"]),
)
.arg(
Arg::with_name("PASSWORD")
.short("k")
.long("password")
.takes_value(true)
.help("Password")
.requires_all(&["SERVER_ADDR", "ENCRYPT_METHOD"]),
let app = clap_app!(shadowsocks =>
(version: shadowsocks::VERSION)
(about: "A fast tunnel proxy that helps you bypass firewalls.")
(@arg VERBOSE: -v ... "Set the level of debug")
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
(@arg TCP_AND_UDP: -U conflicts_with[UDP_ONLY] "Server mode TCP_AND_UDP")
(@arg CONFIG: -c --config +takes_value "Specify config file")
(@arg BIND_ADDR: -b --("bind-addr") +takes_value "Bind address, outbound socket will bind this address")
(@arg SERVER_ADDR: -s --("server-addr") +takes_value requires[PASSWORD ENCRYPT_METHOD] "Server address")
(@arg PASSWORD: -k --password +takes_value requires[SERVER_ADDR ENCRYPT_METHOD] "Password")
(@arg PLUGIN: --plugin +takes_value "Enable SIP003 plugin")
(@arg PLUGIN_OPT: --("plugin-opts") +takes_value requires[PLUGIN] "Set SIP003 plugin options")
(@group SERVER_CONFIG =>
(@attributes +required ... arg[CONFIG SERVER_ADDR URL])
)
(@arg MANAGER_ADDRESS: --("manager-address") +takes_value "ShadowSocks Manager (ssmgr) address, could be \"IP:Port\", \"Domain:Port\" or \"/path/to/unix.sock\"")
(@arg NO_DELAY: --("no-delay") !takes_value "Set no-delay option for socket")
(@arg NOFILE: -n --nofile +takes_value "Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)")
(@arg ACL: --acl +takes_value "Path to ACL (Access Control List)")
);
let matches = app
.arg(
Arg::with_name("ENCRYPT_METHOD")
.short("m")
@@ -93,50 +64,6 @@ fn main() {
.help("Encryption method")
.requires_all(&["SERVER_ADDR", "PASSWORD"]),
)
.arg(
Arg::with_name("PLUGIN")
.long("plugin")
.takes_value(true)
.help("Enable SIP003 plugin"),
)
.arg(
Arg::with_name("PLUGIN_OPT")
.long("plugin-opts")
.takes_value(true)
.help("Set SIP003 plugin options")
.requires("PLUGIN"),
)
.group(
ArgGroup::with_name("SERVER_CONFIG")
.args(&["CONFIG", "SERVER_ADDR"])
.multiple(true)
.required(true),
)
.arg(
Arg::with_name("MANAGER_ADDRESS")
.long("manager-address")
.takes_value(true)
.help("ShadowSocks Manager (ssmgr) address, could be \"IP:Port\", \"Domain:Port\" or \"/path/to/unix.sock\""),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
)
.arg(
Arg::with_name("NOFILE")
.short("n")
.long("nofile")
.takes_value(true)
.help("Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)"),
)
.arg(
Arg::with_name("ACL")
.long("acl")
.takes_value(true)
.help("Path to ACL (Access Control List)"),
)
.arg(
Arg::with_name("IPV6_FIRST")
.short("6")
+10 -27
View File
@@ -3,12 +3,11 @@
//! SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
//! userinfo = websafe-base64-encode-utf8(method ":" password)
use clap::{App, Arg};
use clap::clap_app;
use qrcode::{types::Color, QrCode};
use shadowsocks::{
config::{Config, ConfigType, ServerConfig},
VERSION,
config::{Config, ConfigType, ServerConfig}
};
const BLACK: &str = "\x1b[40m \x1b[0m";
@@ -70,30 +69,14 @@ fn decode(encoded: &str, need_qrcode: bool) {
}
fn main() {
let app = App::new("ssurl")
.about("Encode and decode ShadowSocks URL")
.version(VERSION)
.arg(
Arg::with_name("ENCODE")
.short("e")
.long("encode")
.takes_value(true)
.help("Encode the server configuration in the provided JSON file"),
)
.arg(
Arg::with_name("DECODE")
.short("d")
.long("decode")
.takes_value(true)
.help("Decode the server configuration from the provide ShadowSocks URL"),
)
.arg(
Arg::with_name("QRCODE")
.short("c")
.long("qrcode")
.takes_value(false)
.help("Generate the QRCode with the provided configuration"),
);
let app = clap_app!(ssurl =>
(version: shadowsocks::VERSION)
(about: "Encode and decode ShadowSocks URL")
(@arg ENCODE: -e --encode +takes_value "Encode the server configuration in the provided JSON file")
(@arg DECODE: -d --decode +takes_value "Decode the server configuration from the provide ShadowSocks URL")
(@arg QRCODE: -c --qrcode !takes_value "Generate the QRCode with the provided configuration")
);
let matches = app.get_matches();
let need_qrcode = matches.is_present("QRCODE");
+25 -102
View File
@@ -4,7 +4,7 @@
//! or you could specify a configuration file. The format of configuration file is defined
//! in mod `config`.
use clap::{App, Arg, ArgGroup};
use clap::{Arg, clap_app};
use futures::future::{self, Either};
use log::{error, info};
use tokio::{self, runtime::Builder};
@@ -27,65 +27,32 @@ mod monitor;
fn main() {
let available_ciphers = CipherType::available_ciphers();
let matches = App::new("shadowsocks")
.version(shadowsocks::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls.")
.arg(
Arg::with_name("VERBOSE")
.short("v")
.multiple(true)
.help("Set the level of debug"),
let app = clap_app!(shadowsocks =>
(version: shadowsocks::VERSION)
(about: "A fast tunnel proxy that helps you bypass firewalls.")
(@arg VERBOSE: -v ... "Set the level of debug")
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
(@arg TCP_AND_UDP: -U conflicts_with[UDP_ONLY] "Server mode TCP_AND_UDP")
(@arg CONFIG: -c --config +takes_value "Specify config file")
(@arg LOCAL_ADDR: -b --("local-addr") +takes_value "Local address, listen only to this address if specified")
(@arg FORWARD_ADDR: -f --("foward-addr") +takes_value +required "Forward address, forward to this address")
(@arg SERVER_ADDR: -s --("server-addr") +takes_value requires[PASSWORD ENCRYPT_METHOD] "Server address")
(@arg PASSWORD: -k --password +takes_value requires[SERVER_ADDR ENCRYPT_METHOD] "Password")
(@arg PLUGIN: --plugin +takes_value "Enable SIP003 plugin")
(@arg PLUGIN_OPT: --("plugin-opts") +takes_value requires[PLUGIN] "Set SIP003 plugin options")
(@arg URL: --("server-url") +takes_value "Server address in SIP002 URL")
(@group SERVER_CONFIG =>
(@attributes +required ... arg[CONFIG SERVER_ADDR URL])
)
.arg(
Arg::with_name("UDP_ONLY")
.short("u")
.help("Server mode UDP_ONLY")
.conflicts_with("TCP_AND_UDP"),
)
.arg(
Arg::with_name("TCP_AND_UDP")
.short("U")
.help("Server mode TCP_AND_UDP")
.conflicts_with("UDP_ONLY"),
)
.arg(
Arg::with_name("CONFIG")
.short("c")
.long("config")
.takes_value(true)
.help("Specify config file"),
)
.arg(
Arg::with_name("LOCAL_ADDR")
.short("b")
.long("local-addr")
.takes_value(true)
.help("Local address, listen only to this address if specified"),
)
.arg(
Arg::with_name("FORWARD_ADDR")
.short("f")
.long("foward-addr")
.takes_value(true)
.required(true)
.help("Forward address, forward to this address"),
)
.arg(
Arg::with_name("SERVER_ADDR")
.short("s")
.long("server-addr")
.takes_value(true)
.help("Server address")
.requires_all(&["PASSWORD", "ENCRYPT_METHOD"]),
)
.arg(
Arg::with_name("PASSWORD")
.short("k")
.long("password")
.takes_value(true)
.help("Password")
.requires_all(&["SERVER_ADDR", "ENCRYPT_METHOD"]),
(@group LOCAL_CONFIG =>
(@attributes +required ... arg[CONFIG LOCAL_ADDR])
)
(@arg NO_DELAY: --("no-delay") !takes_value "Set no-delay option for socket")
(@arg NOFILE: -n --nofile +takes_value "Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)")
);
let matches = app
.arg(
Arg::with_name("ENCRYPT_METHOD")
.short("m")
@@ -95,50 +62,6 @@ fn main() {
.help("Encryption method")
.requires_all(&["SERVER_ADDR", "PASSWORD"]),
)
.arg(
Arg::with_name("PLUGIN")
.long("plugin")
.takes_value(true)
.help("Enable SIP003 plugin"),
)
.arg(
Arg::with_name("PLUGIN_OPT")
.long("plugin-opts")
.takes_value(true)
.help("Set SIP003 plugin options")
.requires("PLUGIN"),
)
.arg(
Arg::with_name("URL")
.long("server-url")
.takes_value(true)
.help("Server address in SIP002 URL"),
)
.group(
ArgGroup::with_name("SERVER_CONFIG")
.args(&["CONFIG", "SERVER_ADDR", "URL"])
.multiple(true)
.required(true),
)
.group(
ArgGroup::with_name("LOCAL_CONFIG")
.args(&["CONFIG", "LOCAL_ADDR"])
.multiple(true)
.required(true),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
)
.arg(
Arg::with_name("NOFILE")
.short("n")
.long("nofile")
.takes_value(true)
.help("Set RLIMIT_NOFILE with both soft and hard limit (only for *nix systems)"),
)
.arg(
Arg::with_name("IPV6_FIRST")
.short("6")