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",
|
"failure",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "export_test"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure"
|
name = "failure"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -404,6 +400,15 @@ dependencies = [
|
|||||||
"wit-parser",
|
"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]]
|
[[package]]
|
||||||
name = "fluence-faas"
|
name = "fluence-faas"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -420,10 +425,26 @@ dependencies = [
|
|||||||
"wasmer-wasi",
|
"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]]
|
[[package]]
|
||||||
name = "fluence-sdk-wit"
|
name = "fluence-sdk-wit"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#d5d1207a3db623876bdd6697ca9b1171b46f0813"
|
source = "git+https://github.com/fluencelabs/rust-sdk#cc2b8249fc43d9667a4ec82a2e767f27df100c55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -496,6 +517,13 @@ version = "0.22.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "greeting"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"fluence",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.3.1"
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::instructions_generator::WITGenerator;
|
|
||||||
use crate::default_export_api_config::*;
|
use crate::default_export_api_config::*;
|
||||||
|
use crate::errors::WITGeneratorError;
|
||||||
|
use crate::instructions_generator::WITGenerator;
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
pub use fluence_sdk_wit::FCEAst;
|
pub use fluence_sdk_wit::FCEAst;
|
||||||
use wasmer_wit::ast::Interfaces;
|
use wasmer_wit::ast::Interfaces;
|
||||||
|
|
||||||
// TODO: add error handling
|
|
||||||
/// Parse generated by rust-sdk AST types, generate instructions and embed them to Wasm file.
|
/// 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()
|
let wasm_module = walrus::ModuleConfig::new()
|
||||||
.parse_file(path.clone())
|
.parse_file(path.clone())
|
||||||
.unwrap();
|
.map_err(|e| WITGeneratorError::IOError(format!("{:?} can't be parsed: {:?}", path, e)))?;
|
||||||
let ast_set = wasm_ast_extractor(&wasm_module);
|
|
||||||
|
let ast_set = wasm_ast_extractor(&wasm_module)?;
|
||||||
let interfaces = generate_interfaces(&ast_set);
|
let interfaces = generate_interfaces(&ast_set);
|
||||||
|
|
||||||
let mut wasm_module = wit_parser::embed_wit(wasm_module, &interfaces);
|
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.
|
/// 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();
|
let mut extracted_ast = Vec::new();
|
||||||
|
|
||||||
// consider only sections name of that starts with GENERATED_SECTION_PREFIX
|
// 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 default_ids = walrus::IdsToIndices::default();
|
||||||
let raw_data = custom_module.1.data(&default_ids);
|
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.push(decoded_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
extracted_ast
|
Ok(extracted_ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_interfaces(ast_set: &[FCEAst]) -> Interfaces<'_> {
|
fn generate_interfaces(ast_set: &[FCEAst]) -> Interfaces<'_> {
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
mod default_export_api_config;
|
mod default_export_api_config;
|
||||||
|
mod errors;
|
||||||
mod instructions_generator;
|
mod instructions_generator;
|
||||||
mod interface_generator;
|
mod interface_generator;
|
||||||
|
|
||||||
pub use interface_generator::embed_wit;
|
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]
|
[package]
|
||||||
name = "export_test"
|
name = "greeting"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "export_test"
|
name = "greeting"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
crate-type = ["cdylib"]
|
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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#![allow(clippy::missing_safety_doc)]
|
|
||||||
|
|
||||||
mod mem;
|
use fluence::fce;
|
||||||
mod result;
|
|
||||||
|
|
||||||
use crate::result::{RESULT_PTR, RESULT_SIZE};
|
#[fce]
|
||||||
|
pub fn greeting(name: String) -> String {
|
||||||
#[no_mangle]
|
format!("Hi, {}\n", name)
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
@ -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};
|
use clap::{App, Arg, SubCommand};
|
||||||
|
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
@ -24,13 +40,3 @@ pub fn show_wit<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.short("i")
|
.short("i")
|
||||||
.help("path to the Wasm file")])
|
.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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use crate::Result;
|
||||||
|
use crate::errors::CLIError;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@ -22,12 +25,11 @@ use std::process::Command;
|
|||||||
enum DiagnosticMessage {
|
enum DiagnosticMessage {
|
||||||
BuildScriptExecuted,
|
BuildScriptExecuted,
|
||||||
BuildFinished,
|
BuildFinished,
|
||||||
CompilerArtifact { executable: String },
|
CompilerArtifact { filenames: Vec<String> },
|
||||||
RunWithArgs,
|
RunWithArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add error handling
|
pub(crate) fn build(manifest_path: Option<PathBuf>) -> Result<()> {
|
||||||
pub(crate) fn build(manifest_path: Option<PathBuf>) {
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
let mut cargo = Command::new("cargo");
|
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);
|
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();
|
let mut output = String::new();
|
||||||
|
|
||||||
process
|
process
|
||||||
.stdout
|
.stdout
|
||||||
.take()
|
.take()
|
||||||
.unwrap()
|
.ok_or_else(|| CLIError::WasmCompilationError("Compilation failed: no output".to_string()))?
|
||||||
.read_to_string(&mut output)
|
.read_to_string(&mut output)?;
|
||||||
.unwrap();
|
|
||||||
let _status = process.wait().unwrap();
|
|
||||||
|
|
||||||
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() {
|
for line in output.lines() {
|
||||||
if let Ok(DiagnosticMessage::CompilerArtifact { executable }) = serde_json::from_str(line) {
|
if let Ok(DiagnosticMessage::CompilerArtifact { filenames }) = serde_json::from_str(line) {
|
||||||
wasms.push(executable)
|
wasms.extend(
|
||||||
|
filenames
|
||||||
|
.into_iter()
|
||||||
|
.filter(|name| name.ends_with(".wasm"))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let wasm_path = std::path::PathBuf::from(wasms.first().unwrap());
|
if wasms.is_empty() {
|
||||||
wit_generator::embed_wit(wasm_path);
|
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 args;
|
||||||
mod build;
|
mod build;
|
||||||
|
mod errors;
|
||||||
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use clap::AppSettings;
|
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")
|
let app = App::new("CLI tool for embedding WIT to provided Wasm file")
|
||||||
.version(args::VERSION)
|
.version(args::VERSION)
|
||||||
.author(args::AUTHORS)
|
.author(args::AUTHORS)
|
||||||
.about(args::DESCRIPTION)
|
.about(args::DESCRIPTION)
|
||||||
.setting(AppSettings::ArgRequiredElseHelp)
|
.setting(AppSettings::ArgRequiredElseHelp)
|
||||||
.subcommand(args::build())
|
.subcommand(args::build())
|
||||||
.subcommand(args::show_wit())
|
.subcommand(args::show_wit());
|
||||||
.subcommand(args::validate());
|
|
||||||
|
|
||||||
match app.get_matches().subcommand() {
|
match app.get_matches().subcommand() {
|
||||||
("build", Some(arg)) => {
|
("build", Some(arg)) => {
|
||||||
let manifest_path = arg
|
let manifest_path = arg
|
||||||
.value_of(args::IN_WASM_PATH)
|
.value_of(args::IN_WASM_PATH)
|
||||||
.map(std::path::PathBuf::from);
|
.map(std::path::PathBuf::from);
|
||||||
crate::build::build(manifest_path);
|
|
||||||
|
|
||||||
Ok(())
|
crate::build::build(manifest_path)
|
||||||
}
|
}
|
||||||
("show", Some(arg)) => {
|
("show", Some(arg)) => {
|
||||||
let wasm_path = arg.value_of(args::IN_WASM_PATH).unwrap();
|
let wasm_path = arg.value_of(args::IN_WASM_PATH).unwrap();
|
||||||
@ -59,11 +60,6 @@ pub fn main() -> Result<(), exitfailure::ExitFailure> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
("validate", Some(arg)) => {
|
c => Err(crate::errors::CLIError::NoSuchCommand(c.0.to_string())),
|
||||||
let _wasm_path = arg.value_of(args::IN_WASM_PATH).unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
c => Err(failure::err_msg(format!("Unexpected command: {}", c.0)).into()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user