cargo fmt

This commit is contained in:
Bo Yao
2021-04-21 16:06:12 -07:00
parent 4f220c474b
commit dadc81296a
222 changed files with 7728 additions and 2755 deletions

View File

@@ -59,13 +59,19 @@ pub enum CType {
impl CType {
/// Convenience function to get a mutable void pointer type.
pub fn void_ptr() -> Self {
CType::PointerTo { is_const: false, inner: Box::new(CType::Void) }
CType::PointerTo {
is_const: false,
inner: Box::new(CType::Void),
}
}
/// Convenience function to get a const void pointer type.
#[allow(dead_code)]
pub fn const_void_ptr() -> Self {
CType::PointerTo { is_const: true, inner: Box::new(CType::Void) }
CType::PointerTo {
is_const: true,
inner: Box::new(CType::Void),
}
}
/// Generate the C source code for a type into the given `String`.
@@ -111,10 +117,15 @@ impl CType {
Self::ISize => {
w.push_str("size_t");
}
Self::Function { arguments, return_value } => {
Self::Function {
arguments,
return_value,
} => {
// function with no, name, assume it's a function pointer
let ret: CType =
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default();
let ret: CType = return_value
.as_ref()
.map(|i: &Box<CType>| (&**i).clone())
.unwrap_or_default();
ret.generate_c(w);
w.push(' ');
w.push_str("(*)");
@@ -160,9 +171,14 @@ impl CType {
w.push(' ');
w.push_str(name);
}
Self::Function { arguments, return_value } => {
let ret: CType =
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default();
Self::Function {
arguments,
return_value,
} => {
let ret: CType = return_value
.as_ref()
.map(|i: &Box<CType>| (&**i).clone())
.unwrap_or_default();
ret.generate_c(w);
w.push(' ');
w.push_str(&name);
@@ -248,7 +264,13 @@ impl CStatement {
/// Generate C source code for the given CStatement.
fn generate_c(&self, w: &mut String) {
match &self {
Self::Declaration { name, is_extern, is_const, ctype, definition } => {
Self::Declaration {
name,
is_extern,
is_const,
ctype,
definition,
} => {
if *is_const {
w.push_str("const ");
}
@@ -279,14 +301,20 @@ impl CStatement {
Self::LiteralConstant { value } => {
w.push_str(&value);
}
Self::Cast { target_type, expression } => {
Self::Cast {
target_type,
expression,
} => {
w.push('(');
target_type.generate_c(w);
w.push(')');
w.push(' ');
expression.generate_c(w);
}
Self::TypeDef { source_type, new_name } => {
Self::TypeDef {
source_type,
new_name,
} => {
w.push_str("typedef ");
// leaky abstraction / hack, doesn't fully solve the problem
if let CType::Function { .. } = source_type {
@@ -343,17 +371,26 @@ mod test {
assert_c_type!(CType::ISize, "size_t");
assert_c_type!(CType::TypeDef("my_type".to_string()), "my_type");
assert_c_type!(
CType::Function { arguments: vec![CType::U8, CType::ISize], return_value: None },
CType::Function {
arguments: vec![CType::U8, CType::ISize],
return_value: None
},
"void (*)(unsigned char, size_t)"
);
assert_c_type!(
CType::Function { arguments: vec![], return_value: Some(Box::new(CType::ISize)) },
CType::Function {
arguments: vec![],
return_value: Some(Box::new(CType::ISize))
},
"size_t (*)()"
);
assert_c_type!(
CType::PointerTo {
is_const: true,
inner: Box::new(CType::PointerTo { is_const: false, inner: Box::new(CType::U32) })
inner: Box::new(CType::PointerTo {
is_const: false,
inner: Box::new(CType::U32)
})
},
"const unsigned int**"
);
@@ -384,21 +421,34 @@ mod test {
assert_c_type!(CType::I32, "data", "int data");
assert_c_type!(CType::I64, "data", "long long data");
assert_c_type!(CType::ISize, "data", "size_t data");
assert_c_type!(CType::TypeDef("my_type".to_string()), "data", "my_type data");
assert_c_type!(
CType::Function { arguments: vec![CType::U8, CType::ISize], return_value: None },
CType::TypeDef("my_type".to_string()),
"data",
"my_type data"
);
assert_c_type!(
CType::Function {
arguments: vec![CType::U8, CType::ISize],
return_value: None
},
"my_func",
"void my_func(unsigned char, size_t)"
);
assert_c_type!(
CType::Function { arguments: vec![], return_value: Some(Box::new(CType::ISize)) },
CType::Function {
arguments: vec![],
return_value: Some(Box::new(CType::ISize))
},
"my_func",
"size_t my_func()"
);
assert_c_type!(
CType::PointerTo {
is_const: true,
inner: Box::new(CType::PointerTo { is_const: false, inner: Box::new(CType::U32) })
inner: Box::new(CType::PointerTo {
is_const: false,
inner: Box::new(CType::U32)
})
},
"data",
"const unsigned int** data"
@@ -418,7 +468,9 @@ mod test {
}
assert_c_expr!(
CStatement::LiteralConstant { value: "\"Hello, world!\"".to_string() },
CStatement::LiteralConstant {
value: "\"Hello, world!\"".to_string()
},
"\"Hello, world!\""
);
assert_c_expr!(
@@ -434,9 +486,15 @@ mod test {
assert_c_expr!(
CStatement::LiteralArray {
items: vec![
CStatement::LiteralConstant { value: "1".to_string() },
CStatement::LiteralConstant { value: "2".to_string() },
CStatement::LiteralConstant { value: "3".to_string() },
CStatement::LiteralConstant {
value: "1".to_string()
},
CStatement::LiteralConstant {
value: "2".to_string()
},
CStatement::LiteralConstant {
value: "3".to_string()
},
]
},
"{\n\t1,\n\t2,\n\t3,\n}"
@@ -447,12 +505,20 @@ mod test {
name: "my_array".to_string(),
is_extern: false,
is_const: true,
ctype: CType::Array { inner: Box::new(CType::I32) },
ctype: CType::Array {
inner: Box::new(CType::I32)
},
definition: Some(Box::new(CStatement::LiteralArray {
items: vec![
CStatement::LiteralConstant { value: "1".to_string() },
CStatement::LiteralConstant { value: "2".to_string() },
CStatement::LiteralConstant { value: "3".to_string() },
CStatement::LiteralConstant {
value: "1".to_string()
},
CStatement::LiteralConstant {
value: "2".to_string()
},
CStatement::LiteralConstant {
value: "3".to_string()
},
]
}))
},
@@ -463,7 +529,9 @@ mod test {
name: "my_array".to_string(),
is_extern: true,
is_const: true,
ctype: CType::Array { inner: Box::new(CType::I32) },
ctype: CType::Array {
inner: Box::new(CType::I32)
},
definition: None,
},
"const extern int my_array[];\n"

View File

@@ -94,7 +94,9 @@ pub fn generate_header_file(
name: "WASMER_METADATA".to_string(),
is_extern: true,
is_const: true,
ctype: CType::Array { inner: Box::new(CType::U8) },
ctype: CType::Array {
inner: Box::new(CType::U8),
},
definition: None,
});
let function_declarations = module_info
@@ -111,7 +113,10 @@ pub fn generate_header_file(
name: function_name,
is_extern: false,
is_const: false,
ctype: CType::Function { arguments: vec![CType::Void], return_value: None },
ctype: CType::Function {
arguments: vec![CType::Void],
return_value: None,
},
definition: None,
}
});
@@ -139,7 +144,9 @@ pub fn generate_header_file(
CStatement::Cast {
target_type: CType::void_ptr(),
expression: Box::new(CStatement::LiteralConstant { value: function_name }),
expression: Box::new(CStatement::LiteralConstant {
value: function_name,
}),
}
})
.collect::<Vec<_>>();
@@ -148,7 +155,9 @@ pub fn generate_header_file(
name: "function_pointers".to_string(),
is_extern: false,
is_const: true,
ctype: CType::Array { inner: Box::new(CType::void_ptr()) },
ctype: CType::Array {
inner: Box::new(CType::void_ptr()),
},
definition: Some(Box::new(CStatement::LiteralArray {
items: function_pointer_array_statements,
})),
@@ -156,21 +165,24 @@ pub fn generate_header_file(
}
let func_trampoline_declarations =
module_info.signatures.iter().map(|(sig_index, _func_type)| {
let function_name =
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
module_info
.signatures
.iter()
.map(|(sig_index, _func_type)| {
let function_name =
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
CStatement::Declaration {
name: function_name,
is_extern: false,
is_const: false,
ctype: CType::Function {
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
return_value: None,
},
definition: None,
}
});
CStatement::Declaration {
name: function_name,
is_extern: false,
is_const: false,
ctype: CType::Function {
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
return_value: None,
},
definition: None,
}
});
c_statements.push(CStatement::LiteralConstant {
value: r#"
// Trampolines (functions by which we can call into Wasm) ordered by signature.
@@ -189,7 +201,9 @@ pub fn generate_header_file(
.map(|(sig_index, _vm_shared_index)| {
let function_name =
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
CStatement::LiteralConstant { value: function_name }
CStatement::LiteralConstant {
value: function_name,
}
})
.collect::<Vec<_>>();
@@ -197,15 +211,20 @@ pub fn generate_header_file(
name: "function_trampolines".to_string(),
is_extern: false,
is_const: true,
ctype: CType::Array { inner: Box::new(CType::void_ptr()) },
ctype: CType::Array {
inner: Box::new(CType::void_ptr()),
},
definition: Some(Box::new(CStatement::LiteralArray {
items: function_trampoline_statements,
})),
});
}
let dyn_func_declarations =
module_info.functions.keys().take(module_info.num_imported_functions).map(|func_index| {
let dyn_func_declarations = module_info
.functions
.keys()
.take(module_info.num_imported_functions)
.map(|func_index| {
let function_name =
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
// TODO: figure out the signature here
@@ -247,7 +266,9 @@ pub fn generate_header_file(
.map(|func_index| {
let function_name =
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
CStatement::LiteralConstant { value: function_name }
CStatement::LiteralConstant {
value: function_name,
}
})
.collect::<Vec<_>>();
c_statements.push(CStatement::Declaration {
@@ -263,7 +284,9 @@ pub fn generate_header_file(
});
}
c_statements.push(CStatement::LiteralConstant { value: HELPER_FUNCTIONS.to_string() });
c_statements.push(CStatement::LiteralConstant {
value: HELPER_FUNCTIONS.to_string(),
});
c_statements.push(CStatement::LiteralConstant {
value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),

View File

@@ -19,7 +19,11 @@ use clap::{Clap, ErrorKind};
)]
#[cfg_attr(
feature = "headless",
clap(name = "wasmer-headless", about = "Headless WebAssembly standalone runtime.", author)
clap(
name = "wasmer-headless",
about = "Headless WebAssembly standalone runtime.",
author
)
)]
/// The options for the wasmer Command Line Interface
enum WasmerCLIOptions {

View File

@@ -34,7 +34,8 @@ pub struct Compile {
impl Compile {
/// Runs logic for the `compile` subcommand
pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to compile `{}`", self.path.display()))
self.inner_execute()
.context(format!("failed to compile `{}`", self.path.display()))
}
pub(crate) fn get_recommend_extension(
@@ -62,8 +63,11 @@ impl Compile {
.target_triple
.as_ref()
.map(|target_triple| {
let mut features =
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b);
let mut features = self
.cpu_features
.clone()
.into_iter()
.fold(CpuFeature::set(), |a, b| a | b);
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
// usage
features |= CpuFeature::SSE2;
@@ -94,7 +98,10 @@ impl Compile {
let module = Module::from_file(&store, &self.path)?;
let _ = module.serialize_to_file(&self.output)?;
eprintln!("✔ File compiled successfully to `{}`.", self.output.display(),);
eprintln!(
"✔ File compiled successfully to `{}`.",
self.output.display(),
);
#[cfg(feature = "object-file")]
if engine_type == EngineType::ObjectFile {
@@ -128,7 +135,10 @@ impl Compile {
use std::io::Write;
header.write_all(header_file_src.as_bytes())?;
eprintln!("✔ Header file generated successfully at `{}`.", header_path.display(),);
eprintln!(
"✔ Header file generated successfully at `{}`.",
header_path.display(),
);
}
Ok(())
}

View File

@@ -40,13 +40,21 @@ pub struct Config {
impl Config {
/// Runs logic for the `config` subcommand
pub fn execute(&self) -> Result<()> {
self.inner_execute().context("failed to retrieve the wasmer config".to_string())
self.inner_execute()
.context("failed to retrieve the wasmer config".to_string())
}
fn inner_execute(&self) -> Result<()> {
let key = "WASMER_DIR";
let wasmer_dir = env::var(key)
.or_else(|e| option_env!("WASMER_INSTALL_PREFIX").map(str::to_string).ok_or(e))
.context(format!("failed to retrieve the {} environment variables", key))?;
.or_else(|e| {
option_env!("WASMER_INSTALL_PREFIX")
.map(str::to_string)
.ok_or(e)
})
.context(format!(
"failed to retrieve the {} environment variables",
key
))?;
let prefix = PathBuf::from(wasmer_dir);

View File

@@ -45,8 +45,11 @@ impl CreateExe {
.target_triple
.as_ref()
.map(|target_triple| {
let mut features =
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b);
let mut features = self
.cpu_features
.clone()
.into_iter()
.fold(CpuFeature::set(), |a, b| a | b);
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
// usage
features |= CpuFeature::SSE2;
@@ -54,8 +57,9 @@ impl CreateExe {
})
.unwrap_or_default();
let engine_type = EngineType::ObjectFile;
let (store, compiler_type) =
self.compiler.get_store_for_target_and_engine(target.clone(), engine_type)?;
let (store, compiler_type) = self
.compiler
.get_store_for_target_and_engine(target.clone(), engine_type)?;
println!("Engine: {}", engine_type.to_string());
println!("Compiler: {}", compiler_type.to_string());
@@ -93,7 +97,10 @@ impl CreateExe {
generate_header(header_file_src.as_bytes())?;
self.compile_c(wasm_object_path, output_path)?;
eprintln!("✔ Native executable compiled successfully to `{}`.", self.output.display(),);
eprintln!(
"✔ Native executable compiled successfully to `{}`.",
self.output.display(),
);
Ok(())
}
@@ -149,7 +156,11 @@ fn generate_header(header_file_src: &[u8]) -> anyhow::Result<()> {
fn get_wasmer_dir() -> anyhow::Result<PathBuf> {
Ok(PathBuf::from(
env::var("WASMER_DIR")
.or_else(|e| option_env!("WASMER_INSTALL_PREFIX").map(str::to_string).ok_or(e))
.or_else(|e| {
option_env!("WASMER_INSTALL_PREFIX")
.map(str::to_string)
.ok_or(e)
})
.context("Trying to read env var `WASMER_DIR`")?,
))
}
@@ -257,8 +268,17 @@ impl LinkCode {
let mut command = Command::new(&self.linker_path);
let command = command
.arg(&self.optimization_flag)
.args(self.object_paths.iter().map(|path| path.canonicalize().unwrap()))
.arg(&self.libwasmer_path.canonicalize().context("Failed to find libwasmer")?);
.args(
self.object_paths
.iter()
.map(|path| path.canonicalize().unwrap()),
)
.arg(
&self
.libwasmer_path
.canonicalize()
.context("Failed to find libwasmer")?,
);
let command = if let Some(target) = &self.target {
command.arg("-target").arg(format!("{}", target))
} else {
@@ -267,12 +287,18 @@ impl LinkCode {
// Add libraries required per platform.
// We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers.
#[cfg(windows)]
let command = command.arg("-luserenv").arg("-lWs2_32").arg("-ladvapi32").arg("-lbcrypt");
let command = command
.arg("-luserenv")
.arg("-lWs2_32")
.arg("-ladvapi32")
.arg("-lbcrypt");
// On unix we need dlopen-related symbols, libmath for a few things, and pthreads.
#[cfg(not(windows))]
let command = command.arg("-ldl").arg("-lm").arg("-pthread");
let link_aganist_extra_libs =
self.additional_libraries.iter().map(|lib| format!("-l{}", lib));
let link_aganist_extra_libs = self
.additional_libraries
.iter()
.map(|lib| format!("-l{}", lib));
let command = command.args(link_aganist_extra_libs);
let output = command.arg("-o").arg(&self.output_path).output()?;

View File

@@ -19,13 +19,21 @@ pub struct Inspect {
impl Inspect {
/// Runs logic for the `validate` subcommand
pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to inspect `{}`", self.path.display()))
self.inner_execute()
.context(format!("failed to inspect `{}`", self.path.display()))
}
fn inner_execute(&self) -> Result<()> {
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
let module_contents = std::fs::read(&self.path)?;
let module = Module::new(&store, &module_contents)?;
println!("Type: {}", if !is_wasm(&module_contents) { "wat" } else { "wasm" });
println!(
"Type: {}",
if !is_wasm(&module_contents) {
"wat"
} else {
"wasm"
}
);
println!("Size: {}", ByteSize(module_contents.len() as _));
println!("Imports:");
println!(" Functions:");

View File

@@ -80,7 +80,11 @@ impl Run {
format!(
"failed to run `{}`{}",
self.path.display(),
if CompilerType::enabled().is_empty() { " (no compilers enabled)" } else { "" }
if CompilerType::enabled().is_empty() {
" (no compilers enabled)"
} else {
""
}
)
})
}
@@ -94,7 +98,11 @@ impl Run {
let result = self.invoke_function(&instance, &invoke, &self.args)?;
println!(
"{}",
result.iter().map(|val| val.to_string()).collect::<Vec<String>>().join(" ")
result
.iter()
.map(|val| val.to_string())
.collect::<Vec<String>>()
.join(" ")
);
return Ok(());
}
@@ -149,7 +157,11 @@ impl Run {
let program_name = self
.command_name
.clone()
.or_else(|| self.path.file_name().map(|f| f.to_string_lossy().to_string()))
.or_else(|| {
self.path
.file_name()
.map(|f| f.to_string_lossy().to_string())
})
.unwrap_or_default();
return self
.wasi
@@ -347,19 +359,31 @@ impl Run {
.iter()
.zip(func_ty.params().iter())
.map(|(arg, param_type)| match param_type {
ValType::I32 => Ok(Val::I32(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a i32", arg))?,
ValType::I32 => {
Ok(Val::I32(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a i32", arg)
})?))
}
ValType::I64 => {
Ok(Val::I64(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a i64", arg)
})?))
}
ValType::F32 => {
Ok(Val::F32(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a f32", arg)
})?))
}
ValType::F64 => {
Ok(Val::F64(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a f64", arg)
})?))
}
_ => Err(anyhow!(
"Don't know how to convert {} into {:?}",
arg,
param_type
)),
ValType::I64 => Ok(Val::I64(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a i64", arg))?,
)),
ValType::F32 => Ok(Val::F32(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a f32", arg))?,
)),
ValType::F64 => Ok(Val::F64(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a f64", arg))?,
)),
_ => Err(anyhow!("Don't know how to convert {} into {:?}", arg, param_type)),
})
.collect::<Result<Vec<_>>>()?;
Ok(func.call(&invoke_args)?)

View File

@@ -23,8 +23,10 @@ impl SelfUpdate {
.stdout(Stdio::piped())
.spawn()?;
let mut process =
Command::new("sh").stdin(cmd.stdout.unwrap()).stdout(Stdio::inherit()).spawn()?;
let mut process = Command::new("sh")
.stdin(cmd.stdout.unwrap())
.stdout(Stdio::inherit())
.spawn()?;
process.wait().unwrap();
Ok(())

View File

@@ -18,7 +18,8 @@ pub struct Validate {
impl Validate {
/// Runs logic for the `validate` subcommand
pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to validate `{}`", self.path.display()))
self.inner_execute()
.context(format!("failed to validate `{}`", self.path.display()))
}
fn inner_execute(&self) -> Result<()> {
let (store, _engine_type, _compiler_type) = self.store.get_store()?;

View File

@@ -23,7 +23,8 @@ pub struct Wast {
impl Wast {
/// Runs logic for the `validate` subcommand
pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to test the wast `{}`", self.path.display()))
self.inner_execute()
.context(format!("failed to test the wast `{}`", self.path.display()))
}
fn inner_execute(&self) -> Result<()> {
let (store, _engine_name, _compiler_name) = self.store.get_store()?;

View File

@@ -5,8 +5,10 @@ use std::time;
/// Subroutine to instantiate the loggers
pub fn set_up_logging() -> Result<(), String> {
let colors_line =
ColoredLevelConfig::new().error(Color::Red).warn(Color::Yellow).trace(Color::BrightBlack);
let colors_line = ColoredLevelConfig::new()
.error(Color::Red)
.warn(Color::Yellow)
.trace(Color::BrightBlack);
let should_color = wasmer_should_print_color();
let colors_level = colors_line.info(Color::Green);

View File

@@ -73,7 +73,10 @@ impl CompilerOptions {
} else if self.singlepass {
Ok(CompilerType::Singlepass)
} else if let Some(backend) = self.backend.clone() {
warning!("the `--backend={0}` flag is deprecated, please use `--{0}` instead", backend);
warning!(
"the `--backend={0}` flag is deprecated, please use `--{0}` instead",
backend
);
CompilerType::from_str(&backend)
} else {
// Auto mode, we choose the best compiler for that platform
@@ -155,7 +158,10 @@ impl CompilerOptions {
.engine(),
),
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
engine => bail!("The `{}` engine is not included in this binary.", engine.to_string()),
engine => bail!(
"The `{}` engine is not included in this binary.",
engine.to_string()
),
};
Ok(engine)
@@ -288,7 +294,10 @@ impl CompilerOptions {
}
#[cfg(not(all(feature = "singlepass", feature = "cranelift", feature = "llvm",)))]
compiler => {
bail!("The `{}` compiler is not included in this binary.", compiler.to_string())
bail!(
"The `{}` compiler is not included in this binary.",
compiler.to_string()
)
}
};
@@ -394,7 +403,9 @@ impl StoreOptions {
compiler_config: Box<dyn CompilerConfig>,
) -> Result<(Box<dyn Engine + Send + Sync>, EngineType)> {
let engine_type = self.get_engine()?;
let engine = self.compiler.get_engine_by_type(target, compiler_config, engine_type)?;
let engine = self
.compiler
.get_engine_by_type(target, compiler_config, engine_type)?;
Ok((engine, engine_type))
}
@@ -439,7 +450,10 @@ impl StoreOptions {
Arc::new(wasmer_engine_object_file::ObjectFile::headless().engine())
}
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
engine => bail!("The `{}` engine is not included in this binary.", engine.to_string()),
engine => bail!(
"The `{}` engine is not included in this binary.",
engine.to_string()
),
};
Ok((engine, engine_type))
}

View File

@@ -84,6 +84,9 @@ mod tests {
);
assert_eq!(parse_envvar("A=B").unwrap(), ("A".into(), "B".into()));
assert_eq!(parse_envvar(" A=B\t").unwrap(), ("A".into(), "B".into()));
assert_eq!(parse_envvar("A=B=C=D").unwrap(), ("A".into(), "B=C=D".into()));
assert_eq!(
parse_envvar("A=B=C=D").unwrap(),
("A".into(), "B=C=D".into())
);
}
}