message: add validate subcommand
diff: @@ -28,6 +28,10 @@ enum CLIOptions {
  #[structopt(name = "cache")]
  Cache(Cache),
  + /// Validate a Web Assembly binary
  + #[structopt(name = "validate")]
  + Validate(Validate),
  +
  /// Update wasmer to the latest version
  #[structopt(name = "self-update")]
  SelfUpdate,
  @@ -63,6 +67,13 @@ enum Cache {
  Dir,
  }
  +#[derive(Debug, StructOpt)]
  +struct Validate {
  + /// Input file
  + #[structopt(parse(from_os_str))]
  + path: PathBuf,
  +}
  +
  /// Read the contents of a file
  fn read_file_contents(path: &PathBuf) -> Result<Vec<u8>, io::Error> {
  let mut buffer: Vec<u8> = Vec::new();
  @@ -240,6 +251,49 @@ fn run(options: Run) {
  }
  }
  +fn validate_wasm(validate: Validate) -> Result<(), String> {
  + let wasm_path = validate.path;
  + let wasm_path_as_str = wasm_path.to_str().unwrap();
  +
  + let wasm_binary: Vec<u8> = read_file_contents(&wasm_path).map_err(|err| {
  + format!(
  + "Can't read the file {}: {}",
  + wasm_path.as_os_str().to_string_lossy(),
  + err
  + )
  + })?;
  +
  + if !utils::is_wasm_binary(&wasm_binary) {
  + return Err(format!(
  + "Cannot recognize \"{}\" as a WASM binary",
  + wasm_path_as_str,
  + ));
  + }
  +
  + wabt::Module::read_binary(wasm_binary, &Default::default())
  + .map_err(|err| {
  + format!(
  + "Failed to read \"{}\" as a WASM binary: {}",
  + wasm_path_as_str, err
  + )
  + })?
  + .validate()
  + .map_err(|err| format!("Failed to validate \"{}\": {}", wasm_path_as_str, err))?;
  +
  + Ok(())
  +}
  +
  +/// Runs logic for the `validate` subcommand
  +fn validate(validate: Validate) {
  + match validate_wasm(validate) {
  + Err(message) => {
  + eprintln!("Error: {}", message);
  + exit(-1);
  + }
  + _ => (),
  + }
  +}
  +
  fn main() {
  let options = CLIOptions::from_args();
  match options {
  @@ -264,6 +318,9 @@ fn main() {
  println!("{}", get_cache_dir().to_string_lossy());
  }
  },
  + CLIOptions::Validate(validate_options) => {
  + validate(validate_options);
  + }
  #[cfg(target_os = "windows")]
  CLIOptions::Cache(_) => {
  println!("Caching is disabled for Windows.");
  