Skip to main content

stellar_xdr/cli/
mod.rs

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    /// Channel of XDR to operate on
27    #[arg(value_enum, default_value_t)]
28    channel: Channel,
29    #[command(subcommand)]
30    cmd: Cmd,
31}
32
33impl Root {
34    /// Run the CLIs root command.
35    ///
36    /// ## Errors
37    ///
38    /// If the root command is configured with state that is invalid.
39    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    /// View information about types
71    Types(types::Cmd),
72    /// Guess the XDR type.
73    ///
74    /// Prints a list of types that the XDR values can be decoded into.
75    Guess(guess::Cmd),
76    /// Decode XDR
77    Decode(decode::Cmd),
78    /// Encode XDR
79    Encode(encode::Cmd),
80    Compare(compare::Cmd),
81    Generate(generate::Cmd),
82    /// Preprocess XDR .x files
83    Xfile(xfile::Cmd),
84    /// Print version information
85    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
109/// Run the CLI with the given args.
110///
111/// ## Errors
112///
113/// If the input cannot be parsed.
114pub 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}