stellar_xdr/cli/types/
schema.rs

1use clap::{Args, ValueEnum};
2
3use crate::{cli::Channel, schemars};
4
5#[derive(thiserror::Error, Debug)]
6pub enum Error {
7    #[error("unknown type {0}, choose one of {1:?}")]
8    UnknownType(String, &'static [&'static str]),
9    #[error("error generating JSON: {0}")]
10    GenerateJson(#[from] serde_json::Error),
11}
12
13#[derive(Args, Debug, Clone)]
14#[command()]
15pub struct Cmd {
16    /// XDR type to decode
17    #[arg(long)]
18    pub r#type: String,
19
20    // Output format
21    #[arg(long, value_enum, default_value_t)]
22    pub output: OutputFormat,
23}
24
25#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ValueEnum)]
26pub enum OutputFormat {
27    JsonSchemaDraft201909,
28}
29
30impl Default for OutputFormat {
31    fn default() -> Self {
32        Self::JsonSchemaDraft201909
33    }
34}
35
36macro_rules! run_x {
37    ($f:ident, $m:ident) => {
38        fn $f(&self) -> Result<(), Error> {
39            use std::str::FromStr;
40            let r#type = crate::$m::TypeVariant::from_str(&self.r#type).map_err(|_| {
41                Error::UnknownType(self.r#type.clone(), &crate::$m::TypeVariant::VARIANTS_STR)
42            })?;
43            let settings = match self.output {
44                OutputFormat::JsonSchemaDraft201909 => schemars::settings_draft201909(),
45            };
46            let generator = settings.into_generator();
47            let schema = r#type.json_schema(generator);
48            println!("{}", serde_json::to_string_pretty(&schema)?);
49            Ok(())
50        }
51    };
52}
53
54impl Cmd {
55    /// # Errors
56    /// Fails if the type is unknown or if the JSON generation fails.
57    pub fn run(&self, channel: &Channel) -> Result<(), Error> {
58        match channel {
59            Channel::Curr => self.run_curr()?,
60            Channel::Next => self.run_next()?,
61        }
62        Ok(())
63    }
64
65    run_x!(run_curr, curr);
66    run_x!(run_next, next);
67}