Use try_cast_raw.

This commit is contained in:
Stephen Chung 2023-05-19 13:29:51 +08:00
parent 2a309def54
commit f96c99bbe9
4 changed files with 37 additions and 59 deletions

View File

@ -8,10 +8,7 @@ use crate::{
};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::{type_name, TypeId},
mem,
};
use std::{any::type_name, mem};
/// Options for calling a script-defined function via [`Engine::call_fn_with_options`].
#[derive(Debug, Hash)]
@ -181,20 +178,14 @@ impl Engine {
options,
)
.and_then(|result| {
// Bail out early if the return type needs no cast
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
return Ok(reify! { result => T });
}
// Cast return type
let typ = self.map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
result.try_cast_raw().map_err(|r| {
let result_type = self.map_type_name(r.type_name());
let cast_type = match type_name::<T>() {
typ @ _ if typ.contains("::") => self.map_type_name(typ),
typ @ _ => typ,
};
ERR::ErrorMismatchOutputType(typename.into(), typ.into(), Position::NONE).into()
ERR::ErrorMismatchOutputType(cast_type.into(), result_type.into(), Position::NONE)
.into()
})
})
}

View File

@ -10,7 +10,7 @@ use crate::{
calc_fn_hash, Dynamic, Engine, EvalContext, FnArgsVec, FuncArgs, Position, RhaiResult,
RhaiResultOf, StaticVec, VarDefInfo, ERR,
};
use std::any::{type_name, TypeId};
use std::any::type_name;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
@ -313,19 +313,18 @@ impl<'a> NativeCallContext<'a> {
self._call_fn_raw(fn_name, args, false, false, false)
.and_then(|result| {
// Bail out early if the return type needs no cast
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
return Ok(reify! { result => T });
}
let typ = self.engine().map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
result.try_cast_raw().map_err(|r| {
let result_type = self.engine().map_type_name(r.type_name());
let cast_type = match type_name::<T>() {
typ @ _ if typ.contains("::") => self.engine.map_type_name(typ),
typ @ _ => typ,
};
ERR::ErrorMismatchOutputType(typename.into(), typ.into(), Position::NONE).into()
ERR::ErrorMismatchOutputType(
cast_type.into(),
result_type.into(),
Position::NONE,
)
.into()
})
})
}
@ -347,19 +346,18 @@ impl<'a> NativeCallContext<'a> {
self._call_fn_raw(fn_name, args, true, false, false)
.and_then(|result| {
// Bail out early if the return type needs no cast
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
return Ok(reify! { result => T });
}
let typ = self.engine().map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
result.try_cast_raw().map_err(|r| {
let result_type = self.engine().map_type_name(r.type_name());
let cast_type = match type_name::<T>() {
typ @ _ if typ.contains("::") => self.engine.map_type_name(typ),
typ @ _ => typ,
};
ERR::ErrorMismatchOutputType(typename.into(), typ.into(), Position::NONE).into()
ERR::ErrorMismatchOutputType(
cast_type.into(),
result_type.into(),
Position::NONE,
)
.into()
})
})
}

View File

@ -6,7 +6,6 @@ use crate::ast::ScriptFnDef;
use crate::eval::{Caches, GlobalRuntimeState};
use crate::func::EncapsulatedEnviron;
use crate::{Dynamic, Engine, Position, RhaiResult, Scope, ERR};
use std::mem;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
@ -100,7 +99,7 @@ impl Engine {
global.lib.push(lib.clone());
mem::replace(&mut global.constants, constants.clone())
std::mem::replace(&mut global.constants, constants.clone())
});
#[cfg(feature = "debugging")]

View File

@ -11,7 +11,7 @@ use crate::{
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::{type_name, TypeId},
any::type_name,
convert::{TryFrom, TryInto},
fmt,
hash::{Hash, Hasher},
@ -218,19 +218,14 @@ impl FnPtr {
let ctx = (engine, self.fn_name(), None, &*global, Position::NONE).into();
self.call_raw(&ctx, None, arg_values).and_then(|result| {
// Bail out early if the return type needs no cast
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
return Ok(reify! { result => T });
}
let typ = engine.map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
result.try_cast_raw().map_err(|r| {
let result_type = engine.map_type_name(r.type_name());
let cast_type = match type_name::<T>() {
typ @ _ if typ.contains("::") => engine.map_type_name(typ),
typ @ _ => typ,
};
ERR::ErrorMismatchOutputType(typename.into(), typ.into(), Position::NONE).into()
ERR::ErrorMismatchOutputType(cast_type.into(), result_type.into(), Position::NONE)
.into()
})
})
}
@ -250,19 +245,14 @@ impl FnPtr {
args.parse(&mut arg_values);
self.call_raw(context, None, arg_values).and_then(|result| {
// Bail out early if the return type needs no cast
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
return Ok(reify! { result => T });
}
let typ = context.engine().map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
result.try_cast_raw().map_err(|r| {
let result_type = context.engine().map_type_name(r.type_name());
let cast_type = match type_name::<T>() {
typ @ _ if typ.contains("::") => context.engine().map_type_name(typ),
typ @ _ => typ,
};
ERR::ErrorMismatchOutputType(typename.into(), typ.into(), Position::NONE).into()
ERR::ErrorMismatchOutputType(cast_type.into(), result_type.into(), Position::NONE)
.into()
})
})
}