Make C++ flags available in Rust.

In order to do this, we automagically grab all of C++ gflags and
add them into the Rust Clap command. We then pass through the flags
back to C++ to set them.

This requires different versions of clap to make both our implementation
and autocxx happy.

Change-Id: I36a9584de2ade55390f7109889996bad6e2cd071
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/BUILD b/aos/events/BUILD
index 9910fc6..1a5d7b2 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -282,6 +282,7 @@
         "//aos:flatbuffers_rs",
         "//aos:init_rs",
         "@com_github_google_flatbuffers//rust",
+        "@crate_index//:clap",
         "@crate_index//:futures",
     ],
 )
@@ -309,6 +310,7 @@
         "//aos:flatbuffers_rs",
         "//aos:init_rs",
         "@com_github_google_flatbuffers//rust",
+        "@crate_index//:clap",
         "@crate_index//:futures",
     ],
 )
diff --git a/aos/events/ping.rs b/aos/events/ping.rs
index 3226461..d699d3c 100644
--- a/aos/events/ping.rs
+++ b/aos/events/ping.rs
@@ -1,6 +1,8 @@
 use aos_configuration as config;
 use aos_events_event_loop_runtime::{EventLoopRuntime, Sender, Watcher};
 use aos_events_shm_event_loop::ShmEventLoop;
+use aos_init::WithCppFlags;
+use clap::{CommandFactory, Parser};
 use core::cell::Cell;
 use core::time::Duration;
 use futures::never::Never;
@@ -9,12 +11,22 @@
 use ping_rust_fbs::aos::examples as ping;
 use pong_rust_fbs::aos::examples as pong;
 
+/// Ping portion of a ping/pong system.
+#[derive(Parser, Debug)]
+#[command(name = "ping")]
+struct App {
+    /// Time to sleep between pings.
+    #[arg(long, default_value_t = 10000, value_name = "MICROS")]
+    sleep: u64,
+}
+
 fn main() {
+    let app = App::parse_with_cpp_flags();
     aos_init::init();
     let config = config::read_config_from(Path::new("pingpong_config.json")).unwrap();
     let ping = PingTask::new();
     ShmEventLoop::new(&config).run_with(|runtime| {
-        runtime.spawn(ping.tasks(runtime));
+        runtime.spawn(ping.tasks(runtime, app.sleep));
     });
 }
 
@@ -31,15 +43,15 @@
     }
 
     /// Returns a future with all the tasks for the ping process
-    pub async fn tasks(&self, event_loop: &EventLoopRuntime<'_>) -> Never {
-        futures::join!(self.ping(event_loop), self.handle_pong(event_loop));
+    pub async fn tasks(&self, event_loop: &EventLoopRuntime<'_>, sleep: u64) -> Never {
+        futures::join!(self.ping(event_loop, sleep), self.handle_pong(event_loop));
         unreachable!("Let's hope `never_type` gets stabilized soon :)");
     }
 
-    async fn ping(&self, event_loop: &EventLoopRuntime<'_>) -> Never {
+    async fn ping(&self, event_loop: &EventLoopRuntime<'_>, sleep: u64) -> Never {
         // The sender is used to send messages back to the pong channel.
         let mut ping_sender: Sender<ping::Ping> = event_loop.make_sender("/test").unwrap();
-        let mut interval = event_loop.add_interval(Duration::from_secs(1));
+        let mut interval = event_loop.add_interval(Duration::from_micros(sleep));
 
         event_loop.on_run().await;
         loop {
diff --git a/aos/events/pong.rs b/aos/events/pong.rs
index d2859a8..01af56f 100644
--- a/aos/events/pong.rs
+++ b/aos/events/pong.rs
@@ -1,13 +1,21 @@
 use aos_configuration as config;
 use aos_events_event_loop_runtime::{EventLoopRuntime, Sender, Watcher};
 use aos_events_shm_event_loop::ShmEventLoop;
+use aos_init::WithCppFlags;
+use clap::Parser;
 use futures::never::Never;
 use std::path::Path;
 
 use ping_rust_fbs::aos::examples as ping;
 use pong_rust_fbs::aos::examples as pong;
 
+/// Pong portion of a ping/pong system.
+#[derive(Parser, Debug)]
+#[command(name = "pong")]
+struct App {}
+
 fn main() {
+    let _app = App::parse_with_cpp_flags();
     aos_init::init();
     let config = config::read_config_from(Path::new("pingpong_config.json")).unwrap();
     ShmEventLoop::new(&config).run_with(|runtime| {