diff --git a/Cargo.lock b/Cargo.lock index 2b28e1a..2e139c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,7 +43,7 @@ dependencies = [ [[package]] name = "borsh-cli" -version = "0.1.2" +version = "0.1.3" dependencies = [ "anyhow", "borsh", diff --git a/Cargo.toml b/Cargo.toml index 292fa53..cf1c35d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ description = "Command-line utility for manipulating Borsh-serialized data" edition = "2021" license = "GPL-3.0" name = "borsh-cli" -version = "0.1.2" +version = "0.1.3" [dependencies] anyhow = "1.0.66" diff --git a/src/command/decode.rs b/src/command/decode.rs index 353d26e..da7ac0f 100644 --- a/src/command/decode.rs +++ b/src/command/decode.rs @@ -15,11 +15,16 @@ pub struct DecodeArgs { /// Write output to this file, otherwise to stdout. pub output_path: Option, + + /// Format output + #[arg(short, long)] + pub pretty: bool, } pub struct Decode<'a> { pub input: Vec, pub output: Box, + pub pretty: bool, } impl TryFrom<&'_ DecodeArgs> for Decode<'_> { @@ -29,11 +34,13 @@ impl TryFrom<&'_ DecodeArgs> for Decode<'_> { DecodeArgs { input_path, output_path, + pretty, }: &'_ DecodeArgs, ) -> Result { Ok(Self { input: get_input_bytes(input_path.as_ref())?, output: output_writer(output_path.as_ref())?, + pretty: *pretty, }) } } @@ -48,7 +55,7 @@ impl Execute for Decode<'_> { let value = crate::dynamic_schema::deserialize_from_schema(&mut buf, &schema) .map_err(|_| IOError::DeserializeBorsh("data according to embedded schema"))?; - output_json(&mut self.output, &value) + output_json(&mut self.output, &value, self.pretty) } } @@ -95,6 +102,7 @@ mod tests { let mut p = Decode { input: borsh::try_to_vec_with_schema(&value).unwrap(), output: Box::new(writer), + pretty: false, }; p.execute().unwrap(); diff --git a/src/command/mod.rs b/src/command/mod.rs index 8cd23b6..485fe7f 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -36,13 +36,20 @@ pub enum Command { impl Command { pub fn run(&self) { - match self { - Command::Pack(args) => Pack::execute(&mut args.try_into().unwrap()).unwrap(), - Command::Unpack(args) => Unpack::execute(&mut args.try_into().unwrap()).unwrap(), - Command::Encode(args) => Encode::execute(&mut args.try_into().unwrap()).unwrap(), - Command::Decode(args) => Decode::execute(&mut args.try_into().unwrap()).unwrap(), - Command::Extract(args) => Extract::execute(&mut args.try_into().unwrap()).unwrap(), - Command::Strip(args) => Strip::execute(&mut args.try_into().unwrap()).unwrap(), + #[inline] + fn run_args(args: impl TryInto) -> Result<(), IOError> { + E::execute(&mut args.try_into()?) + } + + if let Err(e) = match self { + Command::Pack(args) => run_args::(args), + Command::Unpack(args) => run_args::(args), + Command::Encode(args) => run_args::(args), + Command::Decode(args) => run_args::(args), + Command::Extract(args) => run_args::(args), + Command::Strip(args) => run_args::(args), + } { + eprintln!("Error: {e}"); } } } @@ -63,7 +70,7 @@ pub enum IOError { WriteBytes, #[error("Failed to deserialize input as Borsh {0}")] DeserializeBorsh(&'static str), - #[error("Failed to deserialize input as Json")] + #[error("Failed to deserialize input as JSON")] DeserializeJson, #[error("Unexpected schema header: {0}")] IncorrectBorshSchemaHeader(String), @@ -101,8 +108,12 @@ fn output_borsh(writer: impl Write, value: impl BorshSerialize) -> Result<(), IO borsh::to_writer(writer, &value).map_err(|_| IOError::WriteBorsh) } -fn output_json(writer: impl Write, value: &impl Serialize) -> Result<(), IOError> { - serde_json::to_writer(writer, value).map_err(|_| IOError::WriteJson) +fn output_json(writer: impl Write, value: &impl Serialize, pretty: bool) -> Result<(), IOError> { + if pretty { + serde_json::to_writer_pretty(writer, value).map_err(|_| IOError::WriteJson) + } else { + serde_json::to_writer(writer, value).map_err(|_| IOError::WriteJson) + } } #[cfg(test)] @@ -162,6 +173,7 @@ mod tests { output_json( &mut output_writer(Some(&"./dataonly.json".into())).unwrap(), &v, + false, // Some(&First::schema_container()), ); output_borsh(