diff --git a/Cargo.lock b/Cargo.lock index d0aabfe4..0c9510a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,12 +315,51 @@ dependencies = [ ] [[package]] -name = "ansi_term" -version = "0.12.1" +name = "anstream" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ - "winapi", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", ] [[package]] @@ -422,7 +461,7 @@ dependencies = [ "futures-lite 2.0.1", "parking", "polling 3.3.1", - "rustix 0.38.25", + "rustix 0.38.26", "slab", "tracing", "windows-sys 0.52.0", @@ -503,17 +542,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -773,25 +801,56 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "4.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap", - "unicode-width", - "vec_map", + "clap_builder", + "clap_derive", ] +[[package]] +name = "clap_builder" +version = "4.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote 1.0.33", + "syn 2.0.39", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + [[package]] name = "color_quant" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "concurrent-queue" version = "2.3.0" @@ -820,9 +879,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -830,9 +889,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" @@ -955,7 +1014,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote 1.0.33", - "strsim 0.10.0", + "strsim", "syn 1.0.109", ] @@ -1853,15 +1912,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.3" @@ -2087,7 +2137,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -2259,9 +2309,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "local-channel" @@ -2604,7 +2654,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi", "libc", ] @@ -2990,7 +3040,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.25", + "rustix 0.38.26", "tracing", "windows-sys 0.52.0", ] @@ -3317,15 +3367,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys 0.4.11", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", ] [[package]] @@ -3690,12 +3740,6 @@ dependencies = [ "regex", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" @@ -3832,7 +3876,7 @@ dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall", - "rustix 0.38.25", + "rustix 0.38.26", "windows-sys 0.48.0", ] @@ -3854,15 +3898,6 @@ dependencies = [ "libc", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "thirtyfour" version = "0.31.0" @@ -4400,12 +4435,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - [[package]] name = "unsafe-libyaml" version = "0.2.9" @@ -4448,6 +4477,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uuid" version = "0.8.2" @@ -4547,12 +4582,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "vergen" version = "7.5.1" @@ -4753,7 +4782,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.25", + "rustix 0.38.26", ] [[package]] @@ -4967,18 +4996,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.27" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43de342578a3a14a9314a2dab1942cbfcbe5686e1f91acdc513058063eafe18" +checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.27" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1012d89e3acb79fad7a799ce96866cfb8098b74638465ea1b1533d35900ca90" +checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" dependencies = [ "proc-macro2", "quote 1.0.33", diff --git a/Cargo.toml b/Cargo.toml index e76c6b7f..fe21cbbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ name = "mavlink-camera-manager" path = "src/main.rs" [dependencies] -clap = "2" +clap = { version = "4.4", features = ["derive"] } regex = "1.9.5" #TODO: Investigate rweb to use openapi spec for free diff --git a/src/cli/manager.rs b/src/cli/manager.rs index 53050189..c0c6c253 100644 --- a/src/cli/manager.rs +++ b/src/cli/manager.rs @@ -5,13 +5,67 @@ use tracing::error; use crate::{custom, stream::gst::utils::PluginRankConfig}; +use clap::Parser; + +#[derive(Parser, Debug)] +#[command(version = env!("CARGO_PKG_VERSION"), author = env!("CARGO_PKG_AUTHORS"), about = env!("CARGO_PKG_DESCRIPTION"))] +struct Args { + /// Sets the mavlink connection string + #[arg(long, value_name = "TYPE>::, + + /// Default settings to be used for different vehicles or environments. + #[arg(long, value_name = "NAME")] + default_settings: Option, + + /// Deletes settings file before starting. + #[arg(long)] + reset: bool, + + /// Sets the address for the REST API server + #[arg(long, value_name = "IP>:, + + /// Specifies the path in witch the logs will be stored. + #[arg(long, default_value = "./logs")] + log_path: Option, + + /// Turns all log categories up to Trace to the log file, for more information check RUST_LOG env variable. + #[arg(long)] + enable_tracing_level_log_file: bool, + + /// Specifies the Dynamic DNS to use as vehicle IP when advertising streams via mavlink. + #[arg(long)] + vehicle_ddns: Option, + + /// Turns on the Tracy tool integration. + #[arg(long)] + enable_tracy: bool, + + /// Enable a thread that prints the number of children processes. + #[arg(long)] + enable_thread_counter: bool, + + /// Enable webrtc thread test with limit of child tasks (can use port for webdriver as parameter). + #[arg(long, value_name = "PORT", num_args = 0..=1, default_missing_value = "9515")] + enable_webrtc_task_test: Option, +} + #[derive(Debug)] -struct Manager<'a> { - clap_matches: clap::ArgMatches<'a>, +struct Manager { + clap_matches: Args, } lazy_static! { - static ref MANAGER: Arc> = Arc::new(Manager::new()); + static ref MANAGER: Arc = Arc::new(Manager::new()); static ref CURRENT_EXECUTION_WWW_PATH: String = format!( "{}/www", std::env::current_exe() @@ -25,10 +79,10 @@ lazy_static! { ); } -impl Manager<'_> { +impl Manager { fn new() -> Self { Self { - clap_matches: get_clap_matches(), + clap_matches: Args::parse(), } } } @@ -40,73 +94,54 @@ pub fn init() { // Check if the verbosity parameter was used pub fn is_verbose() -> bool { - return MANAGER.as_ref().clap_matches.is_present("verbose"); + MANAGER.clap_matches.verbose } pub fn is_tracing() -> bool { - return MANAGER - .as_ref() - .clap_matches - .is_present("enable-tracing-level-log-file"); + MANAGER.clap_matches.enable_tracing_level_log_file } pub fn is_reset() -> bool { - return MANAGER.as_ref().clap_matches.is_present("reset"); + MANAGER.clap_matches.reset } pub fn is_tracy() -> bool { - return MANAGER.as_ref().clap_matches.is_present("enable-tracy"); + MANAGER.clap_matches.enable_tracy } #[allow(dead_code)] // Return the mavlink connection string -pub fn mavlink_connection_string() -> Option<&'static str> { - return MANAGER.as_ref().clap_matches.value_of("mavlink"); +pub fn mavlink_connection_string() -> Option { + MANAGER.clap_matches.mavlink.clone() } pub fn log_path() -> String { MANAGER - .as_ref() .clap_matches - .value_of("log-path") + .log_path + .clone() .expect("Clap arg \"log-path\" should always be \"Some(_)\" because of the default value.") - .to_string() } // Return the desired address for the REST API -pub fn server_address() -> &'static str { - return MANAGER - .as_ref() - .clap_matches - .value_of("rest-server") - .unwrap(); +pub fn server_address() -> String { + MANAGER.clap_matches.rest_server.clone() } -pub fn vehicle_ddns() -> Option<&'static str> { - MANAGER.as_ref().clap_matches.value_of("vehicle-ddns") +pub fn vehicle_ddns() -> Option { + MANAGER.clap_matches.vehicle_ddns.clone() } -pub fn default_settings() -> Option<&'static str> { - return MANAGER.as_ref().clap_matches.value_of("default-settings"); +pub fn default_settings() -> Option { + MANAGER.clap_matches.default_settings.clone() } pub fn enable_thread_counter() -> bool { - return MANAGER - .as_ref() - .clap_matches - .is_present("enable-thread-counter"); + MANAGER.clap_matches.enable_thread_counter } -pub fn enable_webrtc_task_test() -> Option { - let matches = &MANAGER.as_ref().clap_matches; - - if !matches.is_present("enable-webrtc-task-test") { - return None; - } - - matches - .value_of("enable-webrtc-task-test") - .and_then(|value| value.parse::().ok()) +pub fn enable_webrtc_task_test() -> Option { + MANAGER.clap_matches.enable_webrtc_task_test } // Return the command line used to start this application @@ -114,20 +149,15 @@ pub fn command_line_string() -> String { std::env::args().collect::>().join(" ") } -// Return clap::ArgMatches struct -pub fn matches<'a>() -> clap::ArgMatches<'a> { - return MANAGER.as_ref().clap_matches.clone(); +// Return a clone of current Args struct +pub fn command_line() -> String { + format!("{:#?}", MANAGER.clap_matches) } pub fn gst_feature_rank() -> Vec { - let values = MANAGER - .clap_matches - .values_of("gst-feature-rank") - .unwrap_or_default() - .collect::>(); - values + MANAGER.clap_matches.gst_feature_rank .iter() - .filter_map(|&val| { + .filter_map(|val| { if let Some((key, value_str)) = val.split_once('=') { let value = match value_str.parse::() { Ok(value) => value, @@ -153,109 +183,7 @@ pub fn gst_feature_rank() -> Vec { .collect() } -fn get_clap_matches<'a>() -> clap::ArgMatches<'a> { - let version = format!( - "{}-{} ({})", - env!("CARGO_PKG_VERSION"), - env!("VERGEN_GIT_SHA_SHORT"), - env!("VERGEN_BUILD_DATE") - ); - - let matches = clap::App::new(env!("CARGO_PKG_NAME")) - .version(version.as_str()) - .about(env!("CARGO_PKG_DESCRIPTION")) - .author(env!("CARGO_PKG_AUTHORS")) - .arg( - clap::Arg::with_name("mavlink") - .long("mavlink") - .value_name("TYPE>:::= Result<(), String> { +fn gst_feature_rank_validator(val: &str) -> Result { if let Some((_key, value_str)) = val.split_once('=') { if value_str.parse::().is_err() { return Err("GST_RANK_INT_VALUE should be a valid 32 bits signed integer, like \"-1\", \"0\" or \"256\" (without quotes).".to_string()); @@ -263,7 +191,7 @@ fn gst_feature_rank_validator(val: String) -> Result<(), String> { } else { return Err("Unexpected format, it should be =, where GST_PLUGIN_NAME is a string, and GST_RANK_INT_VALUE a valid 32 bits signed integer. Example: \"omxh264enc=264\" (without quotes).".to_string()); } - Ok(()) + Ok(val.into()) } #[cfg(test)] diff --git a/src/custom/mod.rs b/src/custom/mod.rs index 496ef680..292a466d 100644 --- a/src/custom/mod.rs +++ b/src/custom/mod.rs @@ -1,24 +1,21 @@ -use std::str::FromStr; - -use clap::arg_enum; +use clap::ValueEnum; use crate::cli; use crate::video_stream::types::VideoAndStreamInformation; mod bluerov; -arg_enum! { - #[derive(PartialEq, Debug)] - pub enum CustomEnvironment { - BlueROVUDP, - BlueROVRTSP, - } +#[derive(ValueEnum, PartialEq, Debug, Clone)] +#[clap(rename_all = "verbatim")] +pub enum CustomEnvironment { + BlueROVUDP, + BlueROVRTSP, } pub fn create_default_streams() -> Vec { - match cli::manager::default_settings().map(CustomEnvironment::from_str) { - Some(Ok(CustomEnvironment::BlueROVUDP)) => bluerov::udp(), - Some(Ok(CustomEnvironment::BlueROVRTSP)) => bluerov::rtsp(), + match cli::manager::default_settings() { + Some(CustomEnvironment::BlueROVUDP) => bluerov::udp(), + Some(CustomEnvironment::BlueROVRTSP) => bluerov::rtsp(), _ => vec![], } } diff --git a/src/logger/manager.rs b/src/logger/manager.rs index 428c94ff..4f737235 100644 --- a/src/logger/manager.rs +++ b/src/logger/manager.rs @@ -96,7 +96,7 @@ pub fn init() { ); debug!("Command line call: {}", cli::manager::command_line_string()); debug!( - "Command line input struct call: {:#?}", - cli::manager::matches().args + "Command line input struct call: {}", + cli::manager::command_line() ); } diff --git a/src/main.rs b/src/main.rs index 3377e6b8..036fc0ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ async fn main() -> Result<(), std::io::Error> { stream::manager::init(); if let Some(endpoint) = cli::manager::mavlink_connection_string() { - settings::manager::set_mavlink_endpoint(endpoint); + settings::manager::set_mavlink_endpoint(&endpoint); } if cli::manager::enable_thread_counter() { @@ -48,5 +48,5 @@ async fn main() -> Result<(), std::io::Error> { error!("Failed to start default streams. Reason: {error:?}") } - server::manager::run(cli::manager::server_address()).await + server::manager::run(&cli::manager::server_address()).await } diff --git a/src/mavlink/mavlink_camera.rs b/src/mavlink/mavlink_camera.rs index a56893bb..a45736bf 100644 --- a/src/mavlink/mavlink_camera.rs +++ b/src/mavlink/mavlink_camera.rs @@ -117,9 +117,8 @@ impl MavlinkCamera { // and the time MAVLink connection is negotiated with the other MAVLink // systems. let visible_qgc_ip_address = get_visible_qgc_address(); - let server_port = cli::manager::server_address() - .split(':') - .collect::>()[1]; + let address = cli::manager::server_address(); + let server_port = address.split(':').collect::>()[1]; let video_source_path = self.video_source_type.inner().source_string(); Url::parse(&format!( "http://{visible_qgc_ip_address}:{server_port}/xml?file={video_source_path}" diff --git a/src/settings/manager.rs b/src/settings/manager.rs index 844389e0..5310e5e9 100644 --- a/src/settings/manager.rs +++ b/src/settings/manager.rs @@ -172,7 +172,7 @@ pub fn save() { #[allow(dead_code)] pub fn header() -> HeaderSettingsFile { let manager = MANAGER.lock().unwrap(); - return manager.content.as_ref().unwrap().config.header.clone(); + manager.content.as_ref().unwrap().config.header.clone() } pub fn mavlink_endpoint() -> Option {