Pretty-print common type names.

This commit is contained in:
Stephen Chung 2020-03-02 23:16:19 +08:00
parent a4a9102fc5
commit 366188234b
4 changed files with 38 additions and 12 deletions

View File

@ -87,12 +87,14 @@ impl Engine {
self.script_fns.clear(); // Clean up engine self.script_fns.clear(); // Clean up engine
match result { match result {
Err(EvalAltResult::Return(out, pos)) => Ok(*out Err(EvalAltResult::Return(out, pos)) => Ok(*out.downcast::<T>().map_err(|a| {
.downcast::<T>() let name = self.map_type_name((*a).type_name());
.map_err(|a| EvalAltResult::ErrorMismatchOutputType((*a).type_name(), pos))?), EvalAltResult::ErrorMismatchOutputType(name, pos)
})?),
Ok(out) => Ok(*out.downcast::<T>().map_err(|a| { Ok(out) => Ok(*out.downcast::<T>().map_err(|a| {
EvalAltResult::ErrorMismatchOutputType((*a).type_name(), Position::eof()) let name = self.map_type_name((*a).type_name());
EvalAltResult::ErrorMismatchOutputType(name, Position::eof())
})?), })?),
Err(err) => Err(err), Err(err) => Err(err),

View File

@ -149,6 +149,7 @@ pub struct Engine {
pub(crate) script_fns: HashMap<FnSpec, Arc<FnIntExt>>, pub(crate) script_fns: HashMap<FnSpec, Arc<FnIntExt>>,
/// A hashmap containing all iterators known to the engine /// A hashmap containing all iterators known to the engine
type_iterators: HashMap<TypeId, Arc<IteratorFn>>, type_iterators: HashMap<TypeId, Arc<IteratorFn>>,
type_names: HashMap<String, String>,
pub(crate) on_print: Box<dyn Fn(&str)>, pub(crate) on_print: Box<dyn Fn(&str)>,
pub(crate) on_debug: Box<dyn Fn(&str)>, pub(crate) on_debug: Box<dyn Fn(&str)>,
@ -188,9 +189,10 @@ impl Engine {
self.call_fn_raw(ident.into(), args.into_vec(), None, pos) self.call_fn_raw(ident.into(), args.into_vec(), None, pos)
.and_then(|b| { .and_then(|b| {
b.downcast() b.downcast().map(|b| *b).map_err(|a| {
.map(|b| *b) let name = self.map_type_name((*a).type_name());
.map_err(|a| EvalAltResult::ErrorMismatchOutputType((*a).type_name(), pos)) EvalAltResult::ErrorMismatchOutputType(name, pos)
})
}) })
} }
@ -207,7 +209,7 @@ impl Engine {
"Trying to call function {:?} with args {:?}", "Trying to call function {:?} with args {:?}",
ident, ident,
args.iter() args.iter()
.map(|x| Any::type_name(&**x)) .map(|x| { self.map_type_name((**x).type_name()) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
); );
@ -266,13 +268,14 @@ impl Engine {
// Return default value // Return default value
Ok(val.clone()) Ok(val.clone())
} else { } else {
let type_names = args let types_list = args
.iter() .iter()
.map(|x| (*(&**x).into_dynamic()).type_name()) .map(|x| (*(&**x).into_dynamic()).type_name())
.map(|name| self.map_type_name(name))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Err(EvalAltResult::ErrorFunctionNotFound( Err(EvalAltResult::ErrorFunctionNotFound(
format!("{} ({})", ident, type_names.join(", ")), format!("{} ({})", ident, types_list.join(", ")),
pos, pos,
)) ))
} }
@ -908,12 +911,33 @@ impl Engine {
} }
} }
pub(crate) fn map_type_name(&self, name: String) -> String {
self.type_names
.get(&name)
.map(|x| x.clone())
.unwrap_or(name.to_string())
}
/// Make a new engine /// Make a new engine
pub fn new() -> Engine { pub fn new() -> Engine {
// User-friendly names for built-in types
let type_names = [
("alloc::string::String", "string"),
(
"alloc::vec::Vec<alloc::boxed::Box<dyn rhai::any::Any>>",
"array",
),
("alloc::boxed::Box<dyn rhai::any::Any>", "dynamic"),
]
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
let mut engine = Engine { let mut engine = Engine {
fns: HashMap::new(), fns: HashMap::new(),
script_fns: HashMap::new(), script_fns: HashMap::new(),
type_iterators: HashMap::new(), type_iterators: HashMap::new(),
type_names,
on_print: Box::new(|x: &str| println!("{}", x)), on_print: Box::new(|x: &str| println!("{}", x)),
on_debug: Box::new(|x: &str| println!("{}", x)), on_debug: Box::new(|x: &str| println!("{}", x)),
}; };

View File

@ -9,7 +9,7 @@ fn test_decrement() -> Result<(), EvalAltResult> {
let r = engine.eval::<String>("let s = \"test\"; s -= \"ing\"; s"); let r = engine.eval::<String>("let s = \"test\"; s -= \"ing\"; s");
match r { match r {
Err(EvalAltResult::ErrorFunctionNotFound(err, _)) if err.starts_with("- ") => (), Err(EvalAltResult::ErrorFunctionNotFound(err, _)) if err == "- (string, string)" => (),
_ => panic!(), _ => panic!(),
} }

View File

@ -7,7 +7,7 @@ fn test_mismatched_op() {
let r = engine.eval::<i64>("60 + \"hello\""); let r = engine.eval::<i64>("60 + \"hello\"");
match r { match r {
Err(EvalAltResult::ErrorMismatchOutputType(err, _)) if err == "alloc::string::String" => (), Err(EvalAltResult::ErrorMismatchOutputType(err, _)) if err == "string" => (),
_ => panic!(), _ => panic!(),
} }
} }