aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd.rs')
-rw-r--r--src/cmd.rs74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/cmd.rs b/src/cmd.rs
new file mode 100644
index 0000000..79236fa
--- /dev/null
+++ b/src/cmd.rs
@@ -0,0 +1,74 @@
+mod cast;
+mod server;
+mod watch;
+
+use snafu::ResultExt as _;
+
+#[derive(Debug, snafu::Snafu)]
+pub enum Error {
+ #[snafu(display("failed to determine program name: {}", source))]
+ FindProgramName { source: crate::util::Error },
+
+ #[snafu(display("{}", source))]
+ Parse { source: clap::Error },
+
+ #[snafu(display("{}", source))]
+ Cast { source: crate::cmd::cast::Error },
+
+ #[snafu(display("{}", source))]
+ Server { source: crate::cmd::server::Error },
+
+ #[snafu(display("{}", source))]
+ Watch { source: crate::cmd::watch::Error },
+}
+
+pub type Result<T> = std::result::Result<T, Error>;
+
+struct Command {
+ name: &'static str,
+ cmd: &'static for<'a, 'b> Fn(clap::App<'a, 'b>) -> clap::App<'a, 'b>,
+ run: &'static for<'a> Fn(&clap::ArgMatches<'a>) -> Result<()>,
+}
+
+const COMMANDS: &[Command] = &[
+ Command {
+ name: "cast",
+ cmd: &cast::cmd,
+ run: &cast::run,
+ },
+ Command {
+ name: "server",
+ cmd: &server::cmd,
+ run: &server::run,
+ },
+ Command {
+ name: "watch",
+ cmd: &watch::cmd,
+ run: &watch::run,
+ },
+];
+
+pub fn parse<'a>() -> Result<clap::ArgMatches<'a>> {
+ let mut app =
+ clap::App::new(crate::util::program_name().context(FindProgramName)?)
+ .about("Broadcast your terminal for other people to watch")
+ .author(clap::crate_authors!())
+ .version(clap::crate_version!())
+ .setting(clap::AppSettings::SubcommandRequired);
+
+ for cmd in COMMANDS {
+ let subcommand = clap::SubCommand::with_name(cmd.name);
+ app = app.subcommand((cmd.cmd)(subcommand));
+ }
+
+ app.get_matches_safe().context(Parse)
+}
+
+pub fn run(matches: clap::ArgMatches<'_>) -> Result<()> {
+ for cmd in COMMANDS {
+ if let Some(submatches) = matches.subcommand_matches(cmd.name) {
+ return (cmd.run)(&submatches);
+ }
+ }
+ unreachable!()
+}