Skip to content

Commit

Permalink
Add compare sub-command to cli (#398)
Browse files Browse the repository at this point in the history
* Add compare sub-command to cli

* tweak

* fix
  • Loading branch information
leighmcculloch authored Oct 1, 2024
1 parent 08778aa commit 27a6456
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/bin/stellar-xdr/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ fn main() {
cli::Error::Types(_)
| cli::Error::Guess(_)
| cli::Error::Decode(_)
| cli::Error::Encode(_) => {
| cli::Error::Encode(_)
| cli::Error::Compare(_) => {
Error::raw(clap::error::ErrorKind::ValueValidation, e).exit()
}
}
Expand Down
114 changes: 114 additions & 0 deletions src/cli/compare.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use std::{fmt::Debug, fs::File, path::PathBuf, str::FromStr};

use clap::{Args, ValueEnum};

use crate::cli::{skip_whitespace::SkipWhitespace, Channel};

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("unknown type {0}, choose one of {1:?}")]
UnknownType(String, &'static [&'static str]),
#[error("error decoding XDR: {0}")]
ReadXdrCurr(#[from] crate::curr::Error),
#[error("error decoding XDR: {0}")]
ReadXdrNext(#[from] crate::next::Error),
#[error("error reading file: {0}")]
ReadFile(#[from] std::io::Error),
}

/// Compare two XDR values with each other
///
/// Outputs:
/// `-1` when the left XDR value is less than the right XDR value,
/// `0` when the left XDR value is equal to the right XDR value,
/// `1` when the left XDR value is greater than the right XDR value
#[derive(Args, Debug, Clone)]
#[command()]
pub struct Cmd {
/// XDR file to decode and compare with the right value
#[arg()]
left: PathBuf,

/// XDR file to decode and compare with the left value
#[arg()]
right: PathBuf,

/// XDR type of both inputs
#[arg(long)]
r#type: String,

// Input format of the XDR
#[arg(long, value_enum, default_value_t)]
input: InputFormat,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ValueEnum)]
pub enum InputFormat {
Single,
SingleBase64,
}

impl Default for InputFormat {
fn default() -> Self {
Self::SingleBase64
}
}

macro_rules! run_x {
($f:ident, $m:ident) => {
fn $f(&self) -> Result<(), Error> {
let f1 = File::open(&self.left)?;
let f2 = File::open(&self.right)?;
let r#type = crate::$m::TypeVariant::from_str(&self.r#type).map_err(|_| {
Error::UnknownType(self.r#type.clone(), &crate::$m::TypeVariant::VARIANTS_STR)
})?;
let (t1, t2) = match self.input {
InputFormat::Single => {
let t1 = {
let mut l1 = crate::$m::Limited::new(f1, crate::$m::Limits::none());
crate::$m::Type::read_xdr_to_end(r#type, &mut l1)?
};
let t2 = {
let mut l = crate::$m::Limited::new(f2, crate::$m::Limits::none());
crate::$m::Type::read_xdr_to_end(r#type, &mut l)?
};
(t1, t2)
}
InputFormat::SingleBase64 => {
let t1 = {
let sw = SkipWhitespace::new(f1);
let mut l = crate::$m::Limited::new(sw, crate::$m::Limits::none());
crate::$m::Type::read_xdr_base64_to_end(r#type, &mut l)?
};
let t2 = {
let sw = SkipWhitespace::new(f2);
let mut l = crate::$m::Limited::new(sw, crate::$m::Limits::none());
crate::$m::Type::read_xdr_base64_to_end(r#type, &mut l)?
};
(t1, t2)
}
};
let cmp = t1.cmp(&t2) as i8;
println!("{cmp}");
Ok(())
}
};
}

impl Cmd {
/// Run the CLIs decode command.
///
/// ## Errors
///
/// If the command is configured with state that is invalid.
pub fn run(&self, channel: &Channel) -> Result<(), Error> {
match channel {
Channel::Curr => self.run_curr()?,
Channel::Next => self.run_next()?,
}
Ok(())
}

run_x!(run_curr, curr);
run_x!(run_next, next);
}
5 changes: 5 additions & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod compare;
pub mod decode;
pub mod encode;
pub mod guess;
Expand Down Expand Up @@ -39,6 +40,7 @@ impl Root {
Cmd::Guess(c) => c.run(&self.channel)?,
Cmd::Decode(c) => c.run(&self.channel)?,
Cmd::Encode(c) => c.run(&self.channel)?,
Cmd::Compare(c) => c.run(&self.channel)?,
Cmd::Version => version::Cmd::run(),
}
Ok(())
Expand Down Expand Up @@ -69,6 +71,7 @@ pub enum Cmd {
Decode(decode::Cmd),
/// Encode XDR
Encode(encode::Cmd),
Compare(compare::Cmd),
/// Print version information
Version,
}
Expand All @@ -86,6 +89,8 @@ pub enum Error {
Decode(#[from] decode::Error),
#[error("error reading file: {0}")]
Encode(#[from] encode::Error),
#[error(transparent)]
Compare(#[from] compare::Error),
}

/// Run the CLI with the given args.
Expand Down

0 comments on commit 27a6456

Please sign in to comment.