Change command line parsing to clap in serde util #434 (#435)

* Change command line parsing to clap in serde util #434
This commit is contained in:
Caroline Cullen
2018-08-14 15:18:10 -07:00
committed by Dan Gohman
parent ce7b72743c
commit 5f679a7310
2 changed files with 46 additions and 60 deletions

View File

@@ -13,7 +13,7 @@ name = "clif-json"
path = "src/clif-json.rs" path = "src/clif-json.rs"
[dependencies] [dependencies]
docopt = "1" clap = "2.32.0"
serde = "1.0.8" serde = "1.0.8"
serde_derive = "1.0.8" serde_derive = "1.0.8"
serde_json = "1.0" serde_json = "1.0"

View File

@@ -12,49 +12,23 @@
) )
)] )]
extern crate clap;
extern crate cranelift_reader; extern crate cranelift_reader;
extern crate docopt; extern crate serde_json;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate cranelift_codegen; extern crate cranelift_codegen;
extern crate serde_json; use clap::{App, Arg, SubCommand};
use cranelift_reader::parse_functions; use cranelift_reader::parse_functions;
use docopt::Docopt;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::{self, Write}; use std::io::{self, Write};
use std::process; use std::process;
use std::vec::Vec;
mod serde_clif_json; mod serde_clif_json;
const USAGE: &str = " fn call_ser(file: &str, pretty: bool) -> Result<(), String> {
Cranelift JSON serializer/deserializer utility
Usage:
clif-json serialize [-p] <file>
clif-json deserialize <file>
Options:
-p, --pretty print pretty json
";
#[derive(Deserialize, Debug)]
struct Args {
cmd_serialize: bool,
cmd_deserialize: bool,
flag_pretty: bool,
arg_file: Vec<String>,
}
/// A command either succeeds or fails with an error message.
pub type CommandResult = Result<(), String>;
/// Serialize Cranelift IR to JSON
fn call_ser(file: &str, pretty: bool) -> CommandResult {
let ret_of_parse = parse_functions(file); let ret_of_parse = parse_functions(file);
match ret_of_parse { match ret_of_parse {
Ok(funcs) => { Ok(funcs) => {
@@ -68,12 +42,11 @@ fn call_ser(file: &str, pretty: bool) -> CommandResult {
println!("{}", ser_str); println!("{}", ser_str);
Ok(()) Ok(())
} }
Err(_pe) => Err(format!("this was a parsing error")), Err(_pe) => Err(format!("There was a parsing error")),
} }
} }
/// Deserialize JSON to Cranelift IR fn call_de(file: &File) -> Result<(), String> {
fn call_de(file: &File) -> CommandResult {
let de: serde_clif_json::SerObj = match serde_json::from_reader(file) { let de: serde_clif_json::SerObj = match serde_json::from_reader(file) {
Result::Ok(val) => val, Result::Ok(val) => val,
Result::Err(err) => panic!("{}", err), Result::Err(err) => panic!("{}", err),
@@ -82,41 +55,54 @@ fn call_de(file: &File) -> CommandResult {
Ok(()) Ok(())
} }
/// Parse the command line arguments and run the requested command. fn main() {
fn clif_json() -> CommandResult { let matches = App::new("Cranelift JSON serializer/deserializer utility")
// Parse command line arguments. .subcommand(
let args: Args = Docopt::new(USAGE) SubCommand::with_name("serialize")
.and_then(|d| d.help(true).deserialize()) .display_order(1)
.unwrap_or_else(|e| e.exit()); .about("Serializes Cranelift IR into JSON.")
.arg(Arg::with_name("pretty").short("p").help("pretty json"))
.arg(
Arg::with_name("FILE")
.required(true)
.value_name("FILE")
.help("Input file for serialization"),
),
)
.subcommand(
SubCommand::with_name("deserialize")
.about("Deserializes Cranelift IR into JSON.")
.arg(
Arg::with_name("FILE")
.required(true)
.value_name("FILE")
.help("Input file for deserialization"),
),
)
.get_matches();
// Find the sub-command to execute. let res_serde = match matches.subcommand() {
let result = if args.cmd_serialize { ("serialize", Some(m)) => {
if let Some(first_file) = args.arg_file.first() { let mut file =
let mut file = File::open(first_file).expect("Unable to open the file"); File::open(m.value_of("FILE").unwrap()).expect("Unable to open the file");
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents) file.read_to_string(&mut contents)
.expect("Unable to read the file"); .expect("Unable to read the file");
call_ser(&contents, args.flag_pretty)
} else { match m.occurrences_of("pretty") {
Err(format!("No file was passed")) 0 => call_ser(&contents, false),
_ => call_ser(&contents, true),
} }
} else if args.cmd_deserialize { }
if let Some(first_file) = args.arg_file.first() { ("deserialize", Some(m)) => {
let mut file = File::open(first_file).expect("Unable to open the file"); let mut file =
File::open(m.value_of("FILE").unwrap()).expect("Unable to open the file");
call_de(&file) call_de(&file)
} else {
Err(format!("No file was passed"))
} }
} else { _ => Err(format!("Invalid subcommand.")),
// Debugging / shouldn't happen with proper command line handling above.
Err(format!("Unhandled args: {:?}", args))
}; };
result if let Err(mut msg) = res_serde {
}
fn main() {
if let Err(mut msg) = clif_json() {
if !msg.ends_with('\n') { if !msg.ends_with('\n') {
msg.push('\n'); msg.push('\n');
} }