stellar_xdr/cli/
compare.rs1use std::{fmt::Debug, fs::File, path::PathBuf, str::FromStr};
2
3use clap::{Args, ValueEnum};
4
5use crate::cli::{skip_whitespace::SkipWhitespace, Channel};
6
7#[derive(thiserror::Error, Debug)]
8pub enum Error {
9 #[error("unknown type {0}, choose one of {1:?}")]
10 UnknownType(String, &'static [&'static str]),
11 #[error("error decoding XDR: {0}")]
12 ReadXdrCurr(#[from] crate::curr::Error),
13 #[error("error decoding XDR: {0}")]
14 ReadXdrNext(#[from] crate::next::Error),
15 #[error("error reading file: {0}")]
16 ReadFile(#[from] std::io::Error),
17}
18
19#[derive(Args, Debug, Clone)]
26#[command()]
27pub struct Cmd {
28 #[arg()]
30 pub left: PathBuf,
31
32 #[arg()]
34 pub right: PathBuf,
35
36 #[arg(long)]
38 pub r#type: String,
39
40 #[arg(long, value_enum, default_value_t)]
42 pub input: InputFormat,
43}
44
45#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ValueEnum)]
46pub enum InputFormat {
47 Single,
48 SingleBase64,
49}
50
51impl Default for InputFormat {
52 fn default() -> Self {
53 Self::SingleBase64
54 }
55}
56
57macro_rules! run_x {
58 ($f:ident, $m:ident) => {
59 fn $f(&self) -> Result<(), Error> {
60 let f1 = File::open(&self.left)?;
61 let f2 = File::open(&self.right)?;
62 let r#type = crate::$m::TypeVariant::from_str(&self.r#type).map_err(|_| {
63 Error::UnknownType(self.r#type.clone(), &crate::$m::TypeVariant::VARIANTS_STR)
64 })?;
65 let (t1, t2) = match self.input {
66 InputFormat::Single => {
67 let t1 = {
68 let mut l1 = crate::$m::Limited::new(f1, crate::$m::Limits::none());
69 crate::$m::Type::read_xdr_to_end(r#type, &mut l1)?
70 };
71 let t2 = {
72 let mut l = crate::$m::Limited::new(f2, crate::$m::Limits::none());
73 crate::$m::Type::read_xdr_to_end(r#type, &mut l)?
74 };
75 (t1, t2)
76 }
77 InputFormat::SingleBase64 => {
78 let t1 = {
79 let sw = SkipWhitespace::new(f1);
80 let mut l = crate::$m::Limited::new(sw, crate::$m::Limits::none());
81 crate::$m::Type::read_xdr_base64_to_end(r#type, &mut l)?
82 };
83 let t2 = {
84 let sw = SkipWhitespace::new(f2);
85 let mut l = crate::$m::Limited::new(sw, crate::$m::Limits::none());
86 crate::$m::Type::read_xdr_base64_to_end(r#type, &mut l)?
87 };
88 (t1, t2)
89 }
90 };
91 let cmp = t1.cmp(&t2) as i8;
92 println!("{cmp}");
93 Ok(())
94 }
95 };
96}
97
98impl Cmd {
99 pub fn run(&self, channel: &Channel) -> Result<(), Error> {
105 match channel {
106 Channel::Curr => self.run_curr()?,
107 Channel::Next => self.run_next()?,
108 }
109 Ok(())
110 }
111
112 run_x!(run_curr, curr);
113 run_x!(run_next, next);
114}