1pub mod compare;
2pub mod decode;
3pub mod encode;
4pub mod generate;
5pub mod guess;
6pub mod types;
7mod util;
8mod version;
9pub mod xfile;
10
11use clap::{Parser, Subcommand, ValueEnum};
12use std::{ffi::OsString, fmt::Debug};
13
14#[derive(Parser, Debug, Clone)]
15#[command(
16 author,
17 version,
18 about,
19 long_about = None,
20 disable_help_subcommand = true,
21 disable_version_flag = true,
22 disable_colored_help = true,
23 infer_subcommands = true,
24)]
25pub struct Root {
26 #[arg(value_enum, default_value_t)]
28 channel: Channel,
29 #[command(subcommand)]
30 cmd: Cmd,
31}
32
33impl Root {
34 pub fn run(&self) -> Result<(), Error> {
40 match &self.cmd {
41 Cmd::Types(c) => c.run(&self.channel)?,
42 Cmd::Guess(c) => c.run(&self.channel)?,
43 Cmd::Decode(c) => c.run(&self.channel)?,
44 Cmd::Encode(c) => c.run(&self.channel)?,
45 Cmd::Generate(c) => c.run(&self.channel)?,
46 Cmd::Compare(c) => c.run(&self.channel)?,
47 Cmd::Xfile(c) => c.run(&self.channel)?,
48 Cmd::Version => version::Cmd::run(),
49 }
50 Ok(())
51 }
52}
53
54#[derive(ValueEnum, Debug, Clone)]
55pub enum Channel {
56 #[value(name = "+curr")]
57 Curr,
58 #[value(name = "+next")]
59 Next,
60}
61
62impl Default for Channel {
63 fn default() -> Self {
64 Self::Curr
65 }
66}
67
68#[derive(Subcommand, Debug, Clone)]
69pub enum Cmd {
70 Types(types::Cmd),
72 Guess(guess::Cmd),
76 Decode(decode::Cmd),
78 Encode(encode::Cmd),
80 Compare(compare::Cmd),
81 Generate(generate::Cmd),
82 Xfile(xfile::Cmd),
84 Version,
86}
87
88#[derive(thiserror::Error, Debug)]
89#[allow(clippy::enum_variant_names)]
90pub enum Error {
91 #[error("{0}")]
92 Clap(#[from] clap::Error),
93 #[error("{0}")]
94 Types(#[from] types::Error),
95 #[error(transparent)]
96 Guess(#[from] guess::Error),
97 #[error(transparent)]
98 Decode(#[from] decode::Error),
99 #[error(transparent)]
100 Encode(#[from] encode::Error),
101 #[error(transparent)]
102 Generate(#[from] generate::Error),
103 #[error(transparent)]
104 Compare(#[from] compare::Error),
105 #[error(transparent)]
106 Xfile(#[from] xfile::Error),
107}
108
109pub fn run<I, T>(args: I) -> Result<(), Error>
115where
116 I: IntoIterator<Item = T>,
117 T: Into<OsString> + Clone,
118{
119 let root = Root::try_parse_from(args)?;
120 root.run()
121}