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")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{ use std::{any::type_name, mem};
any::{type_name, TypeId},
mem,
};
/// Options for calling a script-defined function via [`Engine::call_fn_with_options`]. /// Options for calling a script-defined function via [`Engine::call_fn_with_options`].
#[derive(Debug, Hash)] #[derive(Debug, Hash)]
@ -181,20 +178,14 @@ impl Engine {
options, options,
) )
.and_then(|result| { .and_then(|result| {
// Bail out early if the return type needs no cast result.try_cast_raw().map_err(|r| {
if TypeId::of::<T>() == TypeId::of::<Dynamic>() { let result_type = self.map_type_name(r.type_name());
return Ok(reify! { result => T }); let cast_type = match type_name::<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>() {
typ @ _ if typ.contains("::") => self.map_type_name(typ), typ @ _ if typ.contains("::") => self.map_type_name(typ),
typ @ _ => 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, calc_fn_hash, Dynamic, Engine, EvalContext, FnArgsVec, FuncArgs, Position, RhaiResult,
RhaiResultOf, StaticVec, VarDefInfo, ERR, RhaiResultOf, StaticVec, VarDefInfo, ERR,
}; };
use std::any::{type_name, TypeId}; use std::any::type_name;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -313,19 +313,18 @@ impl<'a> NativeCallContext<'a> {
self._call_fn_raw(fn_name, args, false, false, false) self._call_fn_raw(fn_name, args, false, false, false)
.and_then(|result| { .and_then(|result| {
// Bail out early if the return type needs no cast result.try_cast_raw().map_err(|r| {
if TypeId::of::<T>() == TypeId::of::<Dynamic>() { let result_type = self.engine().map_type_name(r.type_name());
return Ok(reify! { result => T }); let cast_type = match type_name::<T>() {
}
let typ = self.engine().map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
typ @ _ if typ.contains("::") => self.engine.map_type_name(typ), typ @ _ if typ.contains("::") => self.engine.map_type_name(typ),
typ @ _ => 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) self._call_fn_raw(fn_name, args, true, false, false)
.and_then(|result| { .and_then(|result| {
// Bail out early if the return type needs no cast result.try_cast_raw().map_err(|r| {
if TypeId::of::<T>() == TypeId::of::<Dynamic>() { let result_type = self.engine().map_type_name(r.type_name());
return Ok(reify! { result => T }); let cast_type = match type_name::<T>() {
}
let typ = self.engine().map_type_name(result.type_name());
result.try_cast().ok_or_else(|| {
let typename = match type_name::<T>() {
typ @ _ if typ.contains("::") => self.engine.map_type_name(typ), typ @ _ if typ.contains("::") => self.engine.map_type_name(typ),
typ @ _ => 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::eval::{Caches, GlobalRuntimeState};
use crate::func::EncapsulatedEnviron; use crate::func::EncapsulatedEnviron;
use crate::{Dynamic, Engine, Position, RhaiResult, Scope, ERR}; use crate::{Dynamic, Engine, Position, RhaiResult, Scope, ERR};
use std::mem;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -100,7 +99,7 @@ impl Engine {
global.lib.push(lib.clone()); global.lib.push(lib.clone());
mem::replace(&mut global.constants, constants.clone()) std::mem::replace(&mut global.constants, constants.clone())
}); });
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]

View File

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