mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
improve error handling
This commit is contained in:
parent
8eb4a1da7c
commit
37ce9dafb3
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -340,10 +340,6 @@ dependencies = [
|
||||
"failure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "export_test"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
version = "0.1.8"
|
||||
@ -404,6 +400,15 @@ dependencies = [
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
dependencies = [
|
||||
"fluence-sdk-macro",
|
||||
"fluence-sdk-main",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-faas"
|
||||
version = "0.1.0"
|
||||
@ -420,10 +425,26 @@ dependencies = [
|
||||
"wasmer-wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-macro"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
dependencies = [
|
||||
"fluence-sdk-wit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-main"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-sdk-wit"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#d5d1207a3db623876bdd6697ca9b1171b46f0813"
|
||||
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -496,6 +517,13 @@ version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||
|
||||
[[package]]
|
||||
name = "greeting"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fluence",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.1"
|
||||
|
48
crates/wit-generator/src/errors.rs
Normal file
48
crates/wit-generator/src/errors.rs
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::error::Error;
|
||||
use serde_json::Error as SerdeDeserializationError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WITGeneratorError {
|
||||
/// An error related to serde deserialization.
|
||||
DeserializationError(SerdeDeserializationError),
|
||||
|
||||
/// Various errors occurred during the parsing/emitting a Wasm file.
|
||||
IOError(String),
|
||||
}
|
||||
|
||||
impl Error for WITGeneratorError {}
|
||||
|
||||
impl std::fmt::Display for WITGeneratorError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
WITGeneratorError::DeserializationError(err) => write!(
|
||||
f,
|
||||
"Embedded by rust-sdk metadata could't be parsed by serde: {:?}",
|
||||
err
|
||||
),
|
||||
WITGeneratorError::IOError(err) => write!(f, "I/O error occurred: {:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SerdeDeserializationError> for WITGeneratorError {
|
||||
fn from(err: SerdeDeserializationError) -> Self {
|
||||
WITGeneratorError::DeserializationError(err)
|
||||
}
|
||||
}
|
@ -14,27 +14,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::instructions_generator::WITGenerator;
|
||||
use crate::default_export_api_config::*;
|
||||
use crate::errors::WITGeneratorError;
|
||||
use crate::instructions_generator::WITGenerator;
|
||||
use crate::Result;
|
||||
|
||||
pub use fluence_sdk_wit::FCEAst;
|
||||
use wasmer_wit::ast::Interfaces;
|
||||
|
||||
// TODO: add error handling
|
||||
/// Parse generated by rust-sdk AST types, generate instructions and embed them to Wasm file.
|
||||
pub fn embed_wit(path: std::path::PathBuf) {
|
||||
pub fn embed_wit(path: std::path::PathBuf) -> Result<()> {
|
||||
let wasm_module = walrus::ModuleConfig::new()
|
||||
.parse_file(path.clone())
|
||||
.unwrap();
|
||||
let ast_set = wasm_ast_extractor(&wasm_module);
|
||||
.map_err(|e| WITGeneratorError::IOError(format!("{:?} can't be parsed: {:?}", path, e)))?;
|
||||
|
||||
let ast_set = wasm_ast_extractor(&wasm_module)?;
|
||||
let interfaces = generate_interfaces(&ast_set);
|
||||
|
||||
let mut wasm_module = wit_parser::embed_wit(wasm_module, &interfaces);
|
||||
wasm_module.emit_wasm_file(path).unwrap();
|
||||
wasm_module.emit_wasm_file(path).map_err(|e| {
|
||||
WITGeneratorError::IOError(format!("resulted Wasm fule can't be emitted: {:?}", e))
|
||||
})
|
||||
}
|
||||
|
||||
/// Extract all custom AST types previously embedded by rust-sdk from compiled binary.
|
||||
fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Vec<fluence_sdk_wit::FCEAst> {
|
||||
fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<Vec<fluence_sdk_wit::FCEAst>> {
|
||||
let mut extracted_ast = Vec::new();
|
||||
|
||||
// consider only sections name of that starts with GENERATED_SECTION_PREFIX
|
||||
@ -45,11 +49,11 @@ fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Vec<fluence_sdk_wit::FCEA
|
||||
}) {
|
||||
let default_ids = walrus::IdsToIndices::default();
|
||||
let raw_data = custom_module.1.data(&default_ids);
|
||||
let decoded_json: fluence_sdk_wit::FCEAst = serde_json::from_slice(&raw_data).unwrap();
|
||||
let decoded_json: fluence_sdk_wit::FCEAst = serde_json::from_slice(&raw_data)?;
|
||||
extracted_ast.push(decoded_json);
|
||||
}
|
||||
|
||||
extracted_ast
|
||||
Ok(extracted_ast)
|
||||
}
|
||||
|
||||
fn generate_interfaces(ast_set: &[FCEAst]) -> Interfaces<'_> {
|
||||
|
@ -15,7 +15,11 @@
|
||||
*/
|
||||
|
||||
mod default_export_api_config;
|
||||
mod errors;
|
||||
mod instructions_generator;
|
||||
mod interface_generator;
|
||||
|
||||
pub use interface_generator::embed_wit;
|
||||
pub use errors::WITGeneratorError;
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, WITGeneratorError>;
|
||||
|
@ -1,10 +1,13 @@
|
||||
[package]
|
||||
name = "export_test"
|
||||
name = "greeting"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "export_test"
|
||||
name = "greeting"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
fluence = { git = "https://github.com/fluencelabs/rust-sdk" }
|
||||
|
@ -13,33 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
mod mem;
|
||||
mod result;
|
||||
use fluence::fce;
|
||||
|
||||
use crate::result::{RESULT_PTR, RESULT_SIZE};
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn strlen(str_ptr: *mut u8, str_len: usize) -> usize {
|
||||
let user_name = String::from_raw_parts(str_ptr, str_len, str_len);
|
||||
user_name.len()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn greeting(user_name_ptr: *mut u8, user_name_size: usize) {
|
||||
let user_name = String::from_raw_parts(user_name_ptr, user_name_size, user_name_size);
|
||||
let user_name = format!("Hi, {}\n", user_name);
|
||||
|
||||
log_utf8_string(user_name.as_ptr() as i32, user_name.len() as i32);
|
||||
|
||||
*RESULT_PTR.get_mut() = user_name.as_ptr() as _;
|
||||
*RESULT_SIZE.get_mut() = user_name.len();
|
||||
std::mem::forget(user_name);
|
||||
}
|
||||
|
||||
#[link(wasm_import_module = "logger")]
|
||||
extern "C" {
|
||||
// Writes a byte string of size bytes that starts from ptr to a logger
|
||||
fn log_utf8_string(ptr: i32, size: i32);
|
||||
#[fce]
|
||||
pub fn greeting(name: String) -> String {
|
||||
format!("Hi, {}\n", name)
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::alloc::{alloc as global_alloc, dealloc as global_dealloc, Layout};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
/// Allocates memory area of specified size and returns its address.
|
||||
#[no_mangle]
|
||||
pub unsafe fn allocate(size: usize) -> NonNull<u8> {
|
||||
let layout: Layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
|
||||
NonNull::new_unchecked(global_alloc(layout))
|
||||
}
|
||||
|
||||
/// Deallocates memory area for provided memory pointer and size.
|
||||
#[no_mangle]
|
||||
pub unsafe fn deallocate(ptr: NonNull<u8>, size: usize) {
|
||||
let layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
|
||||
global_dealloc(ptr.as_ptr(), layout);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
|
||||
pub static mut RESULT_PTR: AtomicUsize = AtomicUsize::new(0);
|
||||
pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_result_ptr() -> usize {
|
||||
*RESULT_PTR.get_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn get_result_size() -> usize {
|
||||
*RESULT_SIZE.get_mut()
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
;; allocate function
|
||||
(@interface type (func (param i32) (result i32)))
|
||||
|
||||
;; deallocate function
|
||||
(@interface type (func (param i32 i32)))
|
||||
|
||||
;; greeting function
|
||||
(@interface type (func (param string) (result string)))
|
||||
|
||||
;; strlen function
|
||||
(@interface type (func (param string) (result i32)))
|
||||
|
||||
;; result extractor functions
|
||||
(@interface type (func (result i32)))
|
||||
|
||||
(@interface export "allocate" (func 0))
|
||||
(@interface export "deallocate" (func 1))
|
||||
(@interface export "greeting" (func 2))
|
||||
(@interface export "strlen" (func 3))
|
||||
(@interface export "get_result_size" (func 4))
|
||||
(@interface export "get_result_ptr" (func 4))
|
||||
|
||||
;; greeting export adapter
|
||||
(@interface func (type 2)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 2 ;; call greeting
|
||||
call-core 5 ;; call get_result_ptr
|
||||
call-core 4 ;; call get_result_size
|
||||
string.lift_memory
|
||||
call-core 5 ;; call get_result_ptr
|
||||
call-core 4 ;; call get_result_size
|
||||
call-core 1 ;; call deallocate
|
||||
)
|
||||
|
||||
;; strlen export adapter
|
||||
(@interface func (type 3)
|
||||
arg.get 0
|
||||
string.size
|
||||
call-core 0 ;; call allocate
|
||||
arg.get 0
|
||||
string.lower_memory
|
||||
call-core 3 ;; call strlen
|
||||
)
|
||||
|
||||
;; Implementations
|
||||
(@interface implement (func 2) (func 2))
|
||||
(@interface implement (func 3) (func 3))
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use clap::{App, Arg, SubCommand};
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
@ -24,13 +40,3 @@ pub fn show_wit<'a, 'b>() -> App<'a, 'b> {
|
||||
.short("i")
|
||||
.help("path to the Wasm file")])
|
||||
}
|
||||
|
||||
pub fn validate<'a, 'b>() -> App<'a, 'b> {
|
||||
SubCommand::with_name("validate")
|
||||
.about("validates provided Wasm file to suite Fluence network requirements")
|
||||
.args(&[Arg::with_name(IN_WASM_PATH)
|
||||
.required(true)
|
||||
.takes_value(true)
|
||||
.short("i")
|
||||
.help("path to the wasm file")])
|
||||
}
|
||||
|
@ -14,6 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::Result;
|
||||
use crate::errors::CLIError;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
@ -22,12 +25,11 @@ use std::process::Command;
|
||||
enum DiagnosticMessage {
|
||||
BuildScriptExecuted,
|
||||
BuildFinished,
|
||||
CompilerArtifact { executable: String },
|
||||
CompilerArtifact { filenames: Vec<String> },
|
||||
RunWithArgs,
|
||||
}
|
||||
|
||||
// TODO: add error handling
|
||||
pub(crate) fn build(manifest_path: Option<PathBuf>) {
|
||||
pub(crate) fn build(manifest_path: Option<PathBuf>) -> Result<()> {
|
||||
use std::io::Read;
|
||||
|
||||
let mut cargo = Command::new("cargo");
|
||||
@ -37,25 +39,45 @@ pub(crate) fn build(manifest_path: Option<PathBuf>) {
|
||||
cargo.arg("--manifest-path").arg(wasm_path);
|
||||
}
|
||||
|
||||
let mut process = cargo.stdout(std::process::Stdio::piped()).spawn().unwrap();
|
||||
let mut process = cargo.stdout(std::process::Stdio::piped()).spawn()?;
|
||||
|
||||
let mut output = String::new();
|
||||
|
||||
process
|
||||
.stdout
|
||||
.take()
|
||||
.unwrap()
|
||||
.read_to_string(&mut output)
|
||||
.unwrap();
|
||||
let _status = process.wait().unwrap();
|
||||
.ok_or_else(|| CLIError::WasmCompilationError("Compilation failed: no output".to_string()))?
|
||||
.read_to_string(&mut output)?;
|
||||
|
||||
let mut wasms = Vec::new();
|
||||
let status = process.wait()?;
|
||||
if !status.success() {
|
||||
return Err(CLIError::WasmCompilationError(format!(
|
||||
"Compilation failed with status {}",
|
||||
status
|
||||
)));
|
||||
}
|
||||
|
||||
let mut wasms: Vec<String> = Vec::new();
|
||||
for line in output.lines() {
|
||||
if let Ok(DiagnosticMessage::CompilerArtifact { executable }) = serde_json::from_str(line) {
|
||||
wasms.push(executable)
|
||||
if let Ok(DiagnosticMessage::CompilerArtifact { filenames }) = serde_json::from_str(line) {
|
||||
wasms.extend(
|
||||
filenames
|
||||
.into_iter()
|
||||
.filter(|name| name.ends_with(".wasm"))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let wasm_path = std::path::PathBuf::from(wasms.first().unwrap());
|
||||
wit_generator::embed_wit(wasm_path);
|
||||
if wasms.is_empty() {
|
||||
return Err(CLIError::WasmCompilationError(
|
||||
"Compilation failed: no .wasm files was generated".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
for wasm in wasms {
|
||||
let wasm_path = std::path::PathBuf::from(wasm);
|
||||
wit_generator::embed_wit(wasm_path)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
71
tools/cli/src/errors.rs
Normal file
71
tools/cli/src/errors.rs
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use wit_generator::WITGeneratorError;
|
||||
use wit_parser::WITParserError;
|
||||
|
||||
use std::io::Error as StdIOError;
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CLIError {
|
||||
/// Unknown command was entered by user.
|
||||
NoSuchCommand(String),
|
||||
|
||||
/// An error occurred while generating interface types.
|
||||
WITGeneratorError(WITGeneratorError),
|
||||
|
||||
/// An error occurred while parsing interface types.
|
||||
WITParserError(WITParserError),
|
||||
|
||||
/// An error occurred when no Wasm file was compiled.
|
||||
WasmCompilationError(String),
|
||||
|
||||
/// Various errors related to I/O operations.
|
||||
IOError(StdIOError),
|
||||
}
|
||||
|
||||
impl Error for CLIError {}
|
||||
|
||||
impl std::fmt::Display for CLIError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
CLIError::NoSuchCommand(cmd) => write!(f, "{} is unknown command", cmd),
|
||||
CLIError::WITGeneratorError(err) => write!(f, "{}", err),
|
||||
CLIError::WITParserError(err) => write!(f, "{}", err),
|
||||
CLIError::WasmCompilationError(err) => write!(f, "{}", err),
|
||||
CLIError::IOError(err) => write!(f, "{:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WITGeneratorError> for CLIError {
|
||||
fn from(err: WITGeneratorError) -> Self {
|
||||
CLIError::WITGeneratorError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WITParserError> for CLIError {
|
||||
fn from(err: WITParserError) -> Self {
|
||||
CLIError::WITParserError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StdIOError> for CLIError {
|
||||
fn from(err: StdIOError) -> Self {
|
||||
CLIError::IOError(err)
|
||||
}
|
||||
}
|
@ -27,28 +27,29 @@
|
||||
|
||||
mod args;
|
||||
mod build;
|
||||
mod errors;
|
||||
|
||||
use clap::App;
|
||||
use clap::AppSettings;
|
||||
|
||||
pub fn main() -> Result<(), exitfailure::ExitFailure> {
|
||||
pub(crate) type Result<T> = std::result::Result<T, crate::errors::CLIError>;
|
||||
|
||||
pub fn main() -> Result<()> {
|
||||
let app = App::new("CLI tool for embedding WIT to provided Wasm file")
|
||||
.version(args::VERSION)
|
||||
.author(args::AUTHORS)
|
||||
.about(args::DESCRIPTION)
|
||||
.setting(AppSettings::ArgRequiredElseHelp)
|
||||
.subcommand(args::build())
|
||||
.subcommand(args::show_wit())
|
||||
.subcommand(args::validate());
|
||||
.subcommand(args::show_wit());
|
||||
|
||||
match app.get_matches().subcommand() {
|
||||
("build", Some(arg)) => {
|
||||
let manifest_path = arg
|
||||
.value_of(args::IN_WASM_PATH)
|
||||
.map(std::path::PathBuf::from);
|
||||
crate::build::build(manifest_path);
|
||||
|
||||
Ok(())
|
||||
crate::build::build(manifest_path)
|
||||
}
|
||||
("show", Some(arg)) => {
|
||||
let wasm_path = arg.value_of(args::IN_WASM_PATH).unwrap();
|
||||
@ -59,11 +60,6 @@ pub fn main() -> Result<(), exitfailure::ExitFailure> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
("validate", Some(arg)) => {
|
||||
let _wasm_path = arg.value_of(args::IN_WASM_PATH).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
c => Err(failure::err_msg(format!("Unexpected command: {}", c.0)).into()),
|
||||
c => Err(crate::errors::CLIError::NoSuchCommand(c.0.to_string())),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user