Merge branch 'master' into plugins
This commit is contained in:
commit
4691f7860c
@ -16,11 +16,13 @@ use crate::engine::Map;
|
|||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::{type_name, Any, TypeId},
|
any::{type_name, Any, TypeId},
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
collections::HashMap,
|
|
||||||
fmt,
|
fmt,
|
||||||
string::String,
|
string::String,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use crate::stdlib::collections::HashMap;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::stdlib::vec::Vec;
|
use crate::stdlib::vec::Vec;
|
||||||
|
|
||||||
|
12
src/api.rs
12
src/api.rs
@ -1,10 +1,9 @@
|
|||||||
//! Module that defines the extern API of `Engine`.
|
//! Module that defines the extern API of `Engine`.
|
||||||
|
|
||||||
use crate::any::{Dynamic, Variant};
|
use crate::any::{Dynamic, Variant};
|
||||||
use crate::engine::{make_getter, make_setter, Engine, Imports, State};
|
use crate::engine::{Engine, Imports, State};
|
||||||
use crate::error::ParseError;
|
use crate::error::ParseError;
|
||||||
use crate::fn_native::{IteratorFn, SendSync};
|
use crate::fn_native::{IteratorFn, SendSync};
|
||||||
use crate::fn_register::RegisterFn;
|
|
||||||
use crate::module::{FuncReturn, Module};
|
use crate::module::{FuncReturn, Module};
|
||||||
use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
||||||
use crate::parser::AST;
|
use crate::parser::AST;
|
||||||
@ -13,10 +12,14 @@ use crate::scope::Scope;
|
|||||||
use crate::token::{lex, Position};
|
use crate::token::{lex, Position};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::engine::{FN_IDX_GET, FN_IDX_SET};
|
use crate::engine::{FN_IDX_GET, FN_IDX_SET};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::engine::Map;
|
use crate::{
|
||||||
|
engine::{make_getter, make_setter, Map},
|
||||||
|
fn_register::RegisterFn,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
use crate::{engine::get_script_function_by_signature, fn_args::FuncArgs, utils::StaticVec};
|
use crate::{engine::get_script_function_by_signature, fn_args::FuncArgs, utils::StaticVec};
|
||||||
@ -25,7 +28,6 @@ use crate::stdlib::{
|
|||||||
any::{type_name, TypeId},
|
any::{type_name, TypeId},
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
mem,
|
mem,
|
||||||
string::{String, ToString},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
@ -294,7 +296,7 @@ impl Engine {
|
|||||||
self.type_names
|
self.type_names
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(type_name::<T>().to_string(), name.to_string());
|
.insert(type_name::<T>().into(), name.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
//! Main module defining the script evaluation `Engine`.
|
//! Main module defining the script evaluation `Engine`.
|
||||||
|
|
||||||
use crate::any::{map_std_type_name, Dynamic, Union, Variant};
|
use crate::any::{map_std_type_name, Dynamic, Union};
|
||||||
use crate::calc_fn_hash;
|
use crate::calc_fn_hash;
|
||||||
use crate::fn_call::run_builtin_op_assignment;
|
use crate::fn_call::run_builtin_op_assignment;
|
||||||
use crate::fn_native::{CallableFunction, Callback, FnPtr};
|
use crate::fn_native::{CallableFunction, Callback, FnPtr};
|
||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, ModuleRef};
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::packages::{Package, PackagesCollection, StandardPackage};
|
use crate::packages::{Package, PackagesCollection, StandardPackage};
|
||||||
use crate::parser::{Expr, ImmutableString, ReturnType, Stmt};
|
use crate::parser::{Expr, ReturnType, Stmt};
|
||||||
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||||
@ -15,11 +15,21 @@ use crate::syntax::{CustomSyntax, EvalContext};
|
|||||||
use crate::token::Position;
|
use crate::token::Position;
|
||||||
use crate::utils::StaticVec;
|
use crate::utils::StaticVec;
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
|
use crate::any::Variant;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
use crate::parser::{FnAccess, ScriptFnDef};
|
use crate::parser::{FnAccess, ScriptFnDef};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
use crate::module::{resolvers, ModuleResolver};
|
use crate::module::ModuleResolver;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
use crate::module::resolvers;
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_object"), not(feature = "no_module")))]
|
||||||
|
use crate::utils::ImmutableString;
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
@ -83,9 +93,13 @@ pub const KEYWORD_FN_PTR_CALL: &str = "call";
|
|||||||
pub const KEYWORD_FN_PTR_CURRY: &str = "curry";
|
pub const KEYWORD_FN_PTR_CURRY: &str = "curry";
|
||||||
pub const KEYWORD_THIS: &str = "this";
|
pub const KEYWORD_THIS: &str = "this";
|
||||||
pub const FN_TO_STRING: &str = "to_string";
|
pub const FN_TO_STRING: &str = "to_string";
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub const FN_GET: &str = "get$";
|
pub const FN_GET: &str = "get$";
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub const FN_SET: &str = "set$";
|
pub const FN_SET: &str = "set$";
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub const FN_IDX_GET: &str = "index$get$";
|
pub const FN_IDX_GET: &str = "index$get$";
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub const FN_IDX_SET: &str = "index$set$";
|
pub const FN_IDX_SET: &str = "index$set$";
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub const FN_ANONYMOUS: &str = "anon$";
|
pub const FN_ANONYMOUS: &str = "anon$";
|
||||||
@ -94,6 +108,7 @@ pub const MARKER_BLOCK: &str = "$block$";
|
|||||||
pub const MARKER_IDENT: &str = "$ident$";
|
pub const MARKER_IDENT: &str = "$ident$";
|
||||||
|
|
||||||
/// A type specifying the method of chaining.
|
/// A type specifying the method of chaining.
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
pub enum ChainType {
|
pub enum ChainType {
|
||||||
None,
|
None,
|
||||||
@ -102,6 +117,7 @@ pub enum ChainType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A type that encapsulates a mutation target for an expression with side effects.
|
/// A type that encapsulates a mutation target for an expression with side effects.
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Target<'a> {
|
pub enum Target<'a> {
|
||||||
/// The target is a mutable reference to a `Dynamic` value somewhere.
|
/// The target is a mutable reference to a `Dynamic` value somewhere.
|
||||||
@ -114,6 +130,7 @@ pub enum Target<'a> {
|
|||||||
StringChar(&'a mut Dynamic, usize, Dynamic),
|
StringChar(&'a mut Dynamic, usize, Dynamic),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
impl Target<'_> {
|
impl Target<'_> {
|
||||||
/// Is the `Target` a reference pointing to other data?
|
/// Is the `Target` a reference pointing to other data?
|
||||||
pub fn is_ref(&self) -> bool {
|
pub fn is_ref(&self) -> bool {
|
||||||
@ -134,6 +151,7 @@ impl Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is the `Target` a specific type?
|
/// Is the `Target` a specific type?
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn is<T: Variant + Clone>(&self) -> bool {
|
pub fn is<T: Variant + Clone>(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Target::Ref(r) => r.is::<T>(),
|
Target::Ref(r) => r.is::<T>(),
|
||||||
@ -194,11 +212,13 @@ impl Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
||||||
fn from(value: &'a mut Dynamic) -> Self {
|
fn from(value: &'a mut Dynamic) -> Self {
|
||||||
Self::Ref(value)
|
Self::Ref(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
||||||
fn from(value: T) -> Self {
|
fn from(value: T) -> Self {
|
||||||
Self::Value(value.into())
|
Self::Value(value.into())
|
||||||
@ -407,20 +427,24 @@ impl Default for Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Make getter function
|
/// Make getter function
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[inline(always)]
|
||||||
pub fn make_getter(id: &str) -> String {
|
pub fn make_getter(id: &str) -> String {
|
||||||
format!("{}{}", FN_GET, id)
|
format!("{}{}", FN_GET, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make setter function
|
/// Make setter function
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[inline(always)]
|
||||||
pub fn make_setter(id: &str) -> String {
|
pub fn make_setter(id: &str) -> String {
|
||||||
format!("{}{}", FN_SET, id)
|
format!("{}{}", FN_SET, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print/debug to stdout
|
/// Print/debug to stdout
|
||||||
fn default_print(s: &str) {
|
fn default_print(_s: &str) {
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
println!("{}", s);
|
println!("{}", _s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search for a module within an imports stack.
|
/// Search for a module within an imports stack.
|
||||||
@ -611,6 +635,7 @@ impl Engine {
|
|||||||
|
|
||||||
/// Chain-evaluate a dot/index chain.
|
/// Chain-evaluate a dot/index chain.
|
||||||
/// Position in `EvalAltResult` is `None` and must be set afterwards.
|
/// Position in `EvalAltResult` is `None` and must be set afterwards.
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
fn eval_dot_index_chain_helper(
|
fn eval_dot_index_chain_helper(
|
||||||
&self,
|
&self,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
@ -621,7 +646,7 @@ impl Engine {
|
|||||||
idx_values: &mut StaticVec<Dynamic>,
|
idx_values: &mut StaticVec<Dynamic>,
|
||||||
chain_type: ChainType,
|
chain_type: ChainType,
|
||||||
level: usize,
|
level: usize,
|
||||||
mut new_val: Option<Dynamic>,
|
mut _new_val: Option<Dynamic>,
|
||||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
if chain_type == ChainType::None {
|
if chain_type == ChainType::None {
|
||||||
panic!();
|
panic!();
|
||||||
@ -653,18 +678,19 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, obj_ptr, expr, idx_values, next_chain, level,
|
state, lib, this_ptr, obj_ptr, expr, idx_values, next_chain, level,
|
||||||
new_val,
|
_new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
// xxx[rhs] = new_val
|
// xxx[rhs] = new_val
|
||||||
_ if new_val.is_some() => {
|
_ if _new_val.is_some() => {
|
||||||
let mut new_val = new_val.unwrap();
|
let mut new_val = _new_val.unwrap();
|
||||||
let mut idx_val2 = idx_val.clone();
|
let mut idx_val2 = idx_val.clone();
|
||||||
|
|
||||||
match self.get_indexed_mut(state, lib, target, idx_val, pos, true, level) {
|
match self.get_indexed_mut(state, lib, target, idx_val, pos, true, level) {
|
||||||
// Indexed value is an owned value - the only possibility is an indexer
|
// Indexed value is an owned value - the only possibility is an indexer
|
||||||
// Try to call an index setter
|
// Try to call an index setter
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
Ok(obj_ptr) if obj_ptr.is_value() => {
|
Ok(obj_ptr) if obj_ptr.is_value() => {
|
||||||
let args = &mut [target.as_mut(), &mut idx_val2, &mut new_val];
|
let args = &mut [target.as_mut(), &mut idx_val2, &mut new_val];
|
||||||
|
|
||||||
@ -688,6 +714,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
// No index getter - try to call an index setter
|
// No index getter - try to call an index setter
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
EvalAltResult::ErrorIndexingType(_, _) => {
|
EvalAltResult::ErrorIndexingType(_, _) => {
|
||||||
let args = &mut [target.as_mut(), &mut idx_val2, &mut new_val];
|
let args = &mut [target.as_mut(), &mut idx_val2, &mut new_val];
|
||||||
|
|
||||||
@ -719,13 +746,13 @@ impl Engine {
|
|||||||
// xxx.module::fn_name(...) - syntax error
|
// xxx.module::fn_name(...) - syntax error
|
||||||
Expr::FnCall(_) => unreachable!(),
|
Expr::FnCall(_) => unreachable!(),
|
||||||
// {xxx:map}.id = ???
|
// {xxx:map}.id = ???
|
||||||
Expr::Property(x) if target.is::<Map>() && new_val.is_some() => {
|
Expr::Property(x) if target.is::<Map>() && _new_val.is_some() => {
|
||||||
let ((prop, _, _), pos) = x.as_ref();
|
let ((prop, _, _), pos) = x.as_ref();
|
||||||
let index = prop.clone().into();
|
let index = prop.clone().into();
|
||||||
let mut val =
|
let mut val =
|
||||||
self.get_indexed_mut(state, lib, target, index, *pos, true, level)?;
|
self.get_indexed_mut(state, lib, target, index, *pos, true, level)?;
|
||||||
|
|
||||||
val.set_value(new_val.unwrap())
|
val.set_value(_new_val.unwrap())
|
||||||
.map_err(|err| err.new_position(rhs.position()))?;
|
.map_err(|err| err.new_position(rhs.position()))?;
|
||||||
Ok((Default::default(), true))
|
Ok((Default::default(), true))
|
||||||
}
|
}
|
||||||
@ -739,9 +766,9 @@ impl Engine {
|
|||||||
Ok((val.clone_into_dynamic(), false))
|
Ok((val.clone_into_dynamic(), false))
|
||||||
}
|
}
|
||||||
// xxx.id = ???
|
// xxx.id = ???
|
||||||
Expr::Property(x) if new_val.is_some() => {
|
Expr::Property(x) if _new_val.is_some() => {
|
||||||
let ((_, _, setter), pos) = x.as_ref();
|
let ((_, _, setter), pos) = x.as_ref();
|
||||||
let mut args = [target.as_mut(), new_val.as_mut().unwrap()];
|
let mut args = [target.as_mut(), _new_val.as_mut().unwrap()];
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
state, lib, setter, true, 0, &mut args, is_ref, true, None, level,
|
state, lib, setter, true, 0, &mut args, is_ref, true, None, level,
|
||||||
)
|
)
|
||||||
@ -783,7 +810,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, &mut val, expr, idx_values, next_chain, level,
|
state, lib, this_ptr, &mut val, expr, idx_values, next_chain, level,
|
||||||
new_val,
|
_new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
@ -810,7 +837,7 @@ impl Engine {
|
|||||||
let (result, may_be_changed) = self
|
let (result, may_be_changed) = self
|
||||||
.eval_dot_index_chain_helper(
|
.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, target, expr, idx_values, next_chain,
|
state, lib, this_ptr, target, expr, idx_values, next_chain,
|
||||||
level, new_val,
|
level, _new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))?;
|
.map_err(|err| err.new_position(*pos))?;
|
||||||
|
|
||||||
@ -845,7 +872,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, target, expr, idx_values, next_chain,
|
state, lib, this_ptr, target, expr, idx_values, next_chain,
|
||||||
level, new_val,
|
level, _new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
@ -868,6 +895,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a dot/index chain.
|
/// Evaluate a dot/index chain.
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
fn eval_dot_index_chain(
|
fn eval_dot_index_chain(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
@ -944,6 +972,7 @@ impl Engine {
|
|||||||
/// Any spill-overs are stored in `more`, which is dynamic.
|
/// Any spill-overs are stored in `more`, which is dynamic.
|
||||||
/// The fixed length array is used to avoid an allocation in the overwhelming cases of just a few levels of indexing.
|
/// The fixed length array is used to avoid an allocation in the overwhelming cases of just a few levels of indexing.
|
||||||
/// The total number of values is returned.
|
/// The total number of values is returned.
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
fn eval_indexed_chain(
|
fn eval_indexed_chain(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
@ -1014,6 +1043,7 @@ impl Engine {
|
|||||||
|
|
||||||
/// Get the value at the indexed position of a base type
|
/// Get the value at the indexed position of a base type
|
||||||
/// Position in `EvalAltResult` may be None and should be set afterwards.
|
/// Position in `EvalAltResult` may be None and should be set afterwards.
|
||||||
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
fn get_indexed_mut<'a>(
|
fn get_indexed_mut<'a>(
|
||||||
&self,
|
&self,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
@ -1021,12 +1051,13 @@ impl Engine {
|
|||||||
target: &'a mut Target,
|
target: &'a mut Target,
|
||||||
mut _idx: Dynamic,
|
mut _idx: Dynamic,
|
||||||
idx_pos: Position,
|
idx_pos: Position,
|
||||||
create: bool,
|
_create: bool,
|
||||||
_level: usize,
|
_level: usize,
|
||||||
) -> Result<Target<'a>, Box<EvalAltResult>> {
|
) -> Result<Target<'a>, Box<EvalAltResult>> {
|
||||||
self.inc_operations(state)?;
|
self.inc_operations(state)?;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
let is_ref = target.is_ref();
|
let is_ref = target.is_ref();
|
||||||
|
|
||||||
let val = target.as_mut();
|
let val = target.as_mut();
|
||||||
@ -1057,7 +1088,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Dynamic(Union::Map(map)) => {
|
Dynamic(Union::Map(map)) => {
|
||||||
// val_map[idx]
|
// val_map[idx]
|
||||||
Ok(if create {
|
Ok(if _create {
|
||||||
let index = _idx
|
let index = _idx
|
||||||
.take_immutable_string()
|
.take_immutable_string()
|
||||||
.map_err(|_| EvalAltResult::ErrorStringIndexExpr(idx_pos))?;
|
.map_err(|_| EvalAltResult::ErrorStringIndexExpr(idx_pos))?;
|
||||||
@ -1112,7 +1143,7 @@ impl Engine {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "no_index")]
|
#[cfg(any(feature = "no_index", feature = "no_object"))]
|
||||||
_ => Err(Box::new(EvalAltResult::ErrorIndexingType(
|
_ => Err(Box::new(EvalAltResult::ErrorIndexingType(
|
||||||
self.map_type_name(val.type_name()).into(),
|
self.map_type_name(val.type_name()).into(),
|
||||||
Position::none(),
|
Position::none(),
|
||||||
@ -1289,7 +1320,7 @@ impl Engine {
|
|||||||
let mut rhs_val =
|
let mut rhs_val =
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, rhs_expr, level)?;
|
self.eval_expr(scope, mods, state, lib, this_ptr, rhs_expr, level)?;
|
||||||
|
|
||||||
let new_val = Some(if op.is_empty() {
|
let _new_val = Some(if op.is_empty() {
|
||||||
// Normal assignment
|
// Normal assignment
|
||||||
rhs_val
|
rhs_val
|
||||||
} else {
|
} else {
|
||||||
@ -1312,7 +1343,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(_) => {
|
Expr::Index(_) => {
|
||||||
self.eval_dot_index_chain(
|
self.eval_dot_index_chain(
|
||||||
scope, mods, state, lib, this_ptr, lhs_expr, level, new_val,
|
scope, mods, state, lib, this_ptr, lhs_expr, level, _new_val,
|
||||||
)?;
|
)?;
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
@ -1320,7 +1351,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(_) => {
|
Expr::Dot(_) => {
|
||||||
self.eval_dot_index_chain(
|
self.eval_dot_index_chain(
|
||||||
scope, mods, state, lib, this_ptr, lhs_expr, level, new_val,
|
scope, mods, state, lib, this_ptr, lhs_expr, level, _new_val,
|
||||||
)?;
|
)?;
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
use crate::any::Dynamic;
|
use crate::any::Dynamic;
|
||||||
use crate::calc_fn_hash;
|
use crate::calc_fn_hash;
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
search_imports, search_namespace, search_scope_only, Engine, Imports, State, Target, FN_GET,
|
search_imports, search_namespace, search_scope_only, Engine, Imports, State, KEYWORD_DEBUG,
|
||||||
FN_IDX_GET, FN_IDX_SET, FN_SET, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR,
|
KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_PRINT,
|
||||||
KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
KEYWORD_TYPE_OF,
|
||||||
};
|
};
|
||||||
use crate::error::ParseErrorType;
|
use crate::error::ParseErrorType;
|
||||||
use crate::fn_native::{FnCallArgs, FnPtr};
|
use crate::fn_native::{FnCallArgs, FnPtr};
|
||||||
@ -26,8 +26,11 @@ use crate::{
|
|||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::parser::FLOAT;
|
use crate::parser::FLOAT;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
use crate::engine::{FN_IDX_GET, FN_IDX_SET};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::engine::Map;
|
use crate::engine::{Map, Target, FN_GET, FN_SET};
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::{type_name, TypeId},
|
any::{type_name, TypeId},
|
||||||
@ -41,20 +44,22 @@ use crate::stdlib::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Extract the property name from a getter function name.
|
/// Extract the property name from a getter function name.
|
||||||
fn extract_prop_from_getter(fn_name: &str) -> Option<&str> {
|
#[inline(always)]
|
||||||
|
fn extract_prop_from_getter(_fn_name: &str) -> Option<&str> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if fn_name.starts_with(FN_GET) {
|
if _fn_name.starts_with(FN_GET) {
|
||||||
return Some(&fn_name[FN_GET.len()..]);
|
return Some(&_fn_name[FN_GET.len()..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the property name from a setter function name.
|
/// Extract the property name from a setter function name.
|
||||||
fn extract_prop_from_setter(fn_name: &str) -> Option<&str> {
|
#[inline(always)]
|
||||||
|
fn extract_prop_from_setter(_fn_name: &str) -> Option<&str> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if fn_name.starts_with(FN_SET) {
|
if _fn_name.starts_with(FN_SET) {
|
||||||
return Some(&fn_name[FN_SET.len()..]);
|
return Some(&_fn_name[FN_SET.len()..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@ -261,6 +266,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// index getter function not found?
|
// index getter function not found?
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
if fn_name == FN_IDX_GET && args.len() == 2 {
|
if fn_name == FN_IDX_GET && args.len() == 2 {
|
||||||
return Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
|
return Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||||
format!(
|
format!(
|
||||||
@ -273,6 +279,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// index setter function not found?
|
// index setter function not found?
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
if fn_name == FN_IDX_SET {
|
if fn_name == FN_IDX_SET {
|
||||||
return Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
|
return Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||||
format!(
|
format!(
|
||||||
@ -492,6 +499,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Call a dot method.
|
/// Call a dot method.
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub(crate) fn make_method_call(
|
pub(crate) fn make_method_call(
|
||||||
&self,
|
&self,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
@ -512,9 +520,9 @@ impl Engine {
|
|||||||
// Get a reference to the mutation target Dynamic
|
// Get a reference to the mutation target Dynamic
|
||||||
let obj = target.as_mut();
|
let obj = target.as_mut();
|
||||||
let mut idx = idx_val.cast::<StaticVec<Dynamic>>();
|
let mut idx = idx_val.cast::<StaticVec<Dynamic>>();
|
||||||
let mut fn_name = name.as_ref();
|
let mut _fn_name = name.as_ref();
|
||||||
|
|
||||||
let (result, updated) = if fn_name == KEYWORD_FN_PTR_CALL && obj.is::<FnPtr>() {
|
let (result, updated) = if _fn_name == KEYWORD_FN_PTR_CALL && obj.is::<FnPtr>() {
|
||||||
// FnPtr call
|
// FnPtr call
|
||||||
let fn_ptr = obj.downcast_ref::<FnPtr>().unwrap();
|
let fn_ptr = obj.downcast_ref::<FnPtr>().unwrap();
|
||||||
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
||||||
@ -533,7 +541,7 @@ impl Engine {
|
|||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
state, lib, fn_name, *native, hash, args, false, false, *def_val, level,
|
state, lib, fn_name, *native, hash, args, false, false, *def_val, level,
|
||||||
)
|
)
|
||||||
} else if fn_name == KEYWORD_FN_PTR_CALL && idx.len() > 0 && idx[0].is::<FnPtr>() {
|
} else if _fn_name == KEYWORD_FN_PTR_CALL && idx.len() > 0 && idx[0].is::<FnPtr>() {
|
||||||
// FnPtr call on object
|
// FnPtr call on object
|
||||||
let fn_ptr = idx.remove(0).cast::<FnPtr>();
|
let fn_ptr = idx.remove(0).cast::<FnPtr>();
|
||||||
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
||||||
@ -552,7 +560,7 @@ impl Engine {
|
|||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
state, lib, &fn_name, *native, hash, args, is_ref, true, *def_val, level,
|
state, lib, &fn_name, *native, hash, args, is_ref, true, *def_val, level,
|
||||||
)
|
)
|
||||||
} else if fn_name == KEYWORD_FN_PTR_CURRY && obj.is::<FnPtr>() {
|
} else if _fn_name == KEYWORD_FN_PTR_CURRY && obj.is::<FnPtr>() {
|
||||||
// Curry call
|
// Curry call
|
||||||
let fn_ptr = obj.downcast_ref::<FnPtr>().unwrap();
|
let fn_ptr = obj.downcast_ref::<FnPtr>().unwrap();
|
||||||
Ok((
|
Ok((
|
||||||
@ -569,19 +577,20 @@ impl Engine {
|
|||||||
false,
|
false,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
let redirected;
|
let redirected;
|
||||||
let mut hash = *hash;
|
let mut _hash = *hash;
|
||||||
|
|
||||||
// Check if it is a map method call in OOP style
|
// Check if it is a map method call in OOP style
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if let Some(map) = obj.downcast_ref::<Map>() {
|
if let Some(map) = obj.downcast_ref::<Map>() {
|
||||||
if let Some(val) = map.get(fn_name) {
|
if let Some(val) = map.get(_fn_name) {
|
||||||
if let Some(f) = val.downcast_ref::<FnPtr>() {
|
if let Some(f) = val.downcast_ref::<FnPtr>() {
|
||||||
// Remap the function name
|
// Remap the function name
|
||||||
redirected = f.get_fn_name().clone();
|
redirected = f.get_fn_name().clone();
|
||||||
fn_name = &redirected;
|
_fn_name = &redirected;
|
||||||
// Recalculate the hash based on the new function name
|
// Recalculate the hash based on the new function name
|
||||||
hash = calc_fn_hash(empty(), fn_name, idx.len(), empty());
|
_hash = calc_fn_hash(empty(), _fn_name, idx.len(), empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -591,7 +600,7 @@ impl Engine {
|
|||||||
let args = arg_values.as_mut();
|
let args = arg_values.as_mut();
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
state, lib, fn_name, *native, hash, args, is_ref, true, *def_val, level,
|
state, lib, _fn_name, *native, _hash, args, is_ref, true, *def_val, level,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.map_err(|err| err.new_position(*pos))?;
|
.map_err(|err| err.new_position(*pos))?;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
use crate::any::Dynamic;
|
use crate::any::Dynamic;
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
use crate::plugin::PluginFunction;
|
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
use crate::token::{is_valid_identifier, Position};
|
use crate::token::{is_valid_identifier, Position};
|
||||||
use crate::utils::ImmutableString;
|
use crate::utils::ImmutableString;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::any::{Dynamic, Variant};
|
use crate::any::{Dynamic, Variant};
|
||||||
use crate::calc_fn_hash;
|
use crate::calc_fn_hash;
|
||||||
use crate::engine::{make_getter, make_setter, Engine};
|
use crate::engine::Engine;
|
||||||
use crate::fn_native::{CallableFunction as Func, FnCallArgs, IteratorFn, SendSync};
|
use crate::fn_native::{CallableFunction as Func, FnCallArgs, IteratorFn, SendSync};
|
||||||
use crate::parser::{FnAccess, FnAccess::Public};
|
use crate::parser::{FnAccess, FnAccess::Public};
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
@ -20,8 +20,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::engine::{FN_IDX_GET, FN_IDX_SET};
|
use crate::engine::{FN_IDX_GET, FN_IDX_SET};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use crate::engine::{make_getter, make_setter};
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
@ -35,12 +39,13 @@ use crate::stdlib::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
use crate::stdlib::cell::RefCell;
|
use crate::stdlib::cell::RefCell;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
use crate::stdlib::sync::RwLock;
|
use crate::stdlib::sync::RwLock;
|
||||||
|
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
use crate::any::{Dynamic, Union};
|
use crate::any::{Dynamic, Union};
|
||||||
use crate::calc_fn_hash;
|
use crate::calc_fn_hash;
|
||||||
use crate::engine::{
|
use crate::engine::{Engine, KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
||||||
make_getter, make_setter, Engine, KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT,
|
|
||||||
};
|
|
||||||
use crate::error::{LexError, ParseError, ParseErrorType};
|
use crate::error::{LexError, ParseError, ParseErrorType};
|
||||||
use crate::fn_native::Shared;
|
use crate::fn_native::Shared;
|
||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, ModuleRef};
|
||||||
@ -17,6 +15,9 @@ use crate::utils::{StaticVec, StraightHasherBuilder};
|
|||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
use crate::engine::FN_ANONYMOUS;
|
use crate::engine::FN_ANONYMOUS;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use crate::engine::{make_getter, make_setter};
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
@ -38,6 +39,7 @@ use crate::stdlib::{
|
|||||||
use crate::stdlib::collections::hash_map::DefaultHasher;
|
use crate::stdlib::collections::hash_map::DefaultHasher;
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
use ahash::AHasher;
|
use ahash::AHasher;
|
||||||
|
|
||||||
/// The system integer type.
|
/// The system integer type.
|
||||||
@ -971,6 +973,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a `Variable` into a `Property`. All other variants are untouched.
|
/// Convert a `Variable` into a `Property`. All other variants are untouched.
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub(crate) fn into_property(self) -> Self {
|
pub(crate) fn into_property(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Variable(x) if x.1.is_none() => {
|
Self::Variable(x) if x.1.is_none() => {
|
||||||
@ -1408,6 +1411,7 @@ fn parse_array_literal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a map literal.
|
/// Parse a map literal.
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn parse_map_literal(
|
fn parse_map_literal(
|
||||||
input: &mut TokenStream,
|
input: &mut TokenStream,
|
||||||
state: &mut ParseState,
|
state: &mut ParseState,
|
||||||
@ -1875,6 +1879,7 @@ fn parse_op_assignment_stmt(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Make a dot expression.
|
/// Make a dot expression.
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn make_dot_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseError> {
|
fn make_dot_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseError> {
|
||||||
Ok(match (lhs, rhs) {
|
Ok(match (lhs, rhs) {
|
||||||
// idx_lhs[idx_expr].rhs
|
// idx_lhs[idx_expr].rhs
|
||||||
|
@ -34,10 +34,10 @@ pub enum EvalAltResult {
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
ErrorReadingScriptFile(PathBuf, Position, std::io::Error),
|
ErrorReadingScriptFile(PathBuf, Position, std::io::Error),
|
||||||
|
|
||||||
/// Call to an unknown function. Wrapped value is the name of the function.
|
/// Call to an unknown function. Wrapped value is the signature of the function.
|
||||||
ErrorFunctionNotFound(String, Position),
|
ErrorFunctionNotFound(String, Position),
|
||||||
/// An error has occurred inside a called function.
|
/// An error has occurred inside a called function.
|
||||||
/// Wrapped values re the name of the function and the interior error.
|
/// Wrapped values are the name of the function and the interior error.
|
||||||
ErrorInFunctionCall(String, Box<EvalAltResult>, Position),
|
ErrorInFunctionCall(String, Box<EvalAltResult>, Position),
|
||||||
/// Access to `this` that is not bounded.
|
/// Access to `this` that is not bounded.
|
||||||
ErrorUnboundedThis(Position),
|
ErrorUnboundedThis(Position),
|
||||||
|
@ -8,17 +8,20 @@ use crate::token::Position;
|
|||||||
use crate::utils::ImmutableString;
|
use crate::utils::ImmutableString;
|
||||||
|
|
||||||
use serde::de::{
|
use serde::de::{
|
||||||
DeserializeSeed, Deserializer, EnumAccess, Error, IntoDeserializer, MapAccess, SeqAccess,
|
DeserializeSeed, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor,
|
||||||
VariantAccess, Visitor,
|
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::engine::Array;
|
use crate::engine::Array;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::engine::Map;
|
use crate::engine::Map;
|
||||||
|
|
||||||
use crate::stdlib::{any::type_name, fmt};
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use serde::de::{EnumAccess, VariantAccess};
|
||||||
|
|
||||||
|
use crate::stdlib::{any::type_name, boxed::Box, fmt, string::ToString};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
@ -391,11 +394,11 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
|||||||
self.deserialize_seq(visitor)
|
self.deserialize_seq(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
fn deserialize_map<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
return self.value.downcast_ref::<Map>().map_or_else(
|
return self.value.downcast_ref::<Map>().map_or_else(
|
||||||
|| self.type_error(),
|
|| self.type_error(),
|
||||||
|map| visitor.visit_map(IterateMap::new(map.keys(), map.values())),
|
|map| _visitor.visit_map(IterateMap::new(map.keys(), map.values())),
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
@ -507,6 +510,7 @@ where
|
|||||||
values: VALUES,
|
values: VALUES,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
impl<'a, KEYS, VALUES> IterateMap<'a, KEYS, VALUES>
|
impl<'a, KEYS, VALUES> IterateMap<'a, KEYS, VALUES>
|
||||||
where
|
where
|
||||||
KEYS: Iterator<Item = &'a ImmutableString>,
|
KEYS: Iterator<Item = &'a ImmutableString>,
|
||||||
|
@ -10,30 +10,36 @@ use crate::engine::Array;
|
|||||||
use crate::engine::Map;
|
use crate::engine::Map;
|
||||||
|
|
||||||
use serde::ser::{
|
use serde::ser::{
|
||||||
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
|
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct,
|
||||||
SerializeTupleStruct, Serializer,
|
Serializer,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||||
use serde::ser::SerializeTupleVariant;
|
use serde::ser::SerializeTupleVariant;
|
||||||
|
|
||||||
use crate::stdlib::{fmt, mem};
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use serde::ser::SerializeStructVariant;
|
||||||
|
|
||||||
|
use crate::stdlib::{boxed::Box, fmt, string::ToString};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use crate::stdlib::mem;
|
||||||
|
|
||||||
/// Serializer for `Dynamic` which is kept as a reference.
|
/// Serializer for `Dynamic` which is kept as a reference.
|
||||||
pub struct DynamicSerializer {
|
pub struct DynamicSerializer {
|
||||||
/// Buffer to hold a temporary key.
|
/// Buffer to hold a temporary key.
|
||||||
key: Dynamic,
|
_key: Dynamic,
|
||||||
/// Buffer to hold a temporary value.
|
/// Buffer to hold a temporary value.
|
||||||
value: Dynamic,
|
_value: Dynamic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DynamicSerializer {
|
impl DynamicSerializer {
|
||||||
/// Create a `DynamicSerializer` from a `Dynamic` value.
|
/// Create a `DynamicSerializer` from a `Dynamic` value.
|
||||||
pub fn new(value: Dynamic) -> Self {
|
pub fn new(_value: Dynamic) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key: Default::default(),
|
_key: Default::default(),
|
||||||
value,
|
_value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,13 +289,13 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_variant_index: u32,
|
_variant_index: u32,
|
||||||
variant: &'static str,
|
_variant: &'static str,
|
||||||
value: &T,
|
_value: &T,
|
||||||
) -> Result<Self::Ok, Box<EvalAltResult>> {
|
) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
let content = to_dynamic(value)?;
|
let content = to_dynamic(_value)?;
|
||||||
make_variant(variant, content)
|
make_variant(_variant, content)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
@ -371,13 +377,13 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_variant_index: u32,
|
_variant_index: u32,
|
||||||
variant: &'static str,
|
_variant: &'static str,
|
||||||
len: usize,
|
_len: usize,
|
||||||
) -> Result<Self::SerializeStructVariant, Box<EvalAltResult>> {
|
) -> Result<Self::SerializeStructVariant, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
return Ok(StructVariantSerializer {
|
return Ok(StructVariantSerializer {
|
||||||
variant,
|
variant: _variant,
|
||||||
map: Map::with_capacity(len),
|
map: Map::with_capacity(_len),
|
||||||
});
|
});
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
@ -399,7 +405,7 @@ impl SerializeSeq for DynamicSerializer {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
{
|
{
|
||||||
let _value = _value.serialize(&mut *self)?;
|
let _value = _value.serialize(&mut *self)?;
|
||||||
let arr = self.value.downcast_mut::<Array>().unwrap();
|
let arr = self._value.downcast_mut::<Array>().unwrap();
|
||||||
arr.push(_value);
|
arr.push(_value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -410,7 +416,7 @@ impl SerializeSeq for DynamicSerializer {
|
|||||||
// Close the sequence.
|
// Close the sequence.
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
return Ok(self.value);
|
return Ok(self._value);
|
||||||
#[cfg(feature = "no_index")]
|
#[cfg(feature = "no_index")]
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -427,7 +433,7 @@ impl SerializeTuple for DynamicSerializer {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
{
|
{
|
||||||
let _value = _value.serialize(&mut *self)?;
|
let _value = _value.serialize(&mut *self)?;
|
||||||
let arr = self.value.downcast_mut::<Array>().unwrap();
|
let arr = self._value.downcast_mut::<Array>().unwrap();
|
||||||
arr.push(_value);
|
arr.push(_value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -437,7 +443,7 @@ impl SerializeTuple for DynamicSerializer {
|
|||||||
|
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
return Ok(self.value);
|
return Ok(self._value);
|
||||||
#[cfg(feature = "no_index")]
|
#[cfg(feature = "no_index")]
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -454,7 +460,7 @@ impl SerializeTupleStruct for DynamicSerializer {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
{
|
{
|
||||||
let _value = _value.serialize(&mut *self)?;
|
let _value = _value.serialize(&mut *self)?;
|
||||||
let arr = self.value.downcast_mut::<Array>().unwrap();
|
let arr = self._value.downcast_mut::<Array>().unwrap();
|
||||||
arr.push(_value);
|
arr.push(_value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -464,7 +470,7 @@ impl SerializeTupleStruct for DynamicSerializer {
|
|||||||
|
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
return Ok(self.value);
|
return Ok(self._value);
|
||||||
#[cfg(feature = "no_index")]
|
#[cfg(feature = "no_index")]
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -474,10 +480,10 @@ impl SerializeMap for DynamicSerializer {
|
|||||||
type Ok = Dynamic;
|
type Ok = Dynamic;
|
||||||
type Error = Box<EvalAltResult>;
|
type Error = Box<EvalAltResult>;
|
||||||
|
|
||||||
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Box<EvalAltResult>> {
|
fn serialize_key<T: ?Sized + Serialize>(&mut self, _key: &T) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
self.key = key.serialize(&mut *self)?;
|
self._key = _key.serialize(&mut *self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
@ -486,11 +492,11 @@ impl SerializeMap for DynamicSerializer {
|
|||||||
|
|
||||||
fn serialize_value<T: ?Sized + Serialize>(
|
fn serialize_value<T: ?Sized + Serialize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: &T,
|
_value: &T,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
let key = mem::take(&mut self.key)
|
let key = mem::take(&mut self._key)
|
||||||
.take_immutable_string()
|
.take_immutable_string()
|
||||||
.map_err(|typ| {
|
.map_err(|typ| {
|
||||||
Box::new(EvalAltResult::ErrorMismatchOutputType(
|
Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
@ -499,9 +505,9 @@ impl SerializeMap for DynamicSerializer {
|
|||||||
Position::none(),
|
Position::none(),
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let value = value.serialize(&mut *self)?;
|
let _value = _value.serialize(&mut *self)?;
|
||||||
let map = self.value.downcast_mut::<Map>().unwrap();
|
let map = self._value.downcast_mut::<Map>().unwrap();
|
||||||
map.insert(key, value);
|
map.insert(key, _value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
@ -510,22 +516,22 @@ impl SerializeMap for DynamicSerializer {
|
|||||||
|
|
||||||
fn serialize_entry<K: ?Sized + Serialize, T: ?Sized + Serialize>(
|
fn serialize_entry<K: ?Sized + Serialize, T: ?Sized + Serialize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
key: &K,
|
_key: &K,
|
||||||
value: &T,
|
_value: &T,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
let key: Dynamic = key.serialize(&mut *self)?;
|
let _key: Dynamic = _key.serialize(&mut *self)?;
|
||||||
let key = key.take_immutable_string().map_err(|typ| {
|
let _key = _key.take_immutable_string().map_err(|typ| {
|
||||||
Box::new(EvalAltResult::ErrorMismatchOutputType(
|
Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
"string".into(),
|
"string".into(),
|
||||||
typ.into(),
|
typ.into(),
|
||||||
Position::none(),
|
Position::none(),
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let value = value.serialize(&mut *self)?;
|
let _value = _value.serialize(&mut *self)?;
|
||||||
let map = self.value.downcast_mut::<Map>().unwrap();
|
let map = self._value.downcast_mut::<Map>().unwrap();
|
||||||
map.insert(key, value);
|
map.insert(_key, _value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
@ -534,7 +540,7 @@ impl SerializeMap for DynamicSerializer {
|
|||||||
|
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
return Ok(self.value);
|
return Ok(self._value);
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -546,14 +552,14 @@ impl SerializeStruct for DynamicSerializer {
|
|||||||
|
|
||||||
fn serialize_field<T: ?Sized + Serialize>(
|
fn serialize_field<T: ?Sized + Serialize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
key: &'static str,
|
_key: &'static str,
|
||||||
value: &T,
|
_value: &T,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
let value = value.serialize(&mut *self)?;
|
let _value = _value.serialize(&mut *self)?;
|
||||||
let map = self.value.downcast_mut::<Map>().unwrap();
|
let map = self._value.downcast_mut::<Map>().unwrap();
|
||||||
map.insert(key.into(), value);
|
map.insert(_key.into(), _value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
@ -562,7 +568,7 @@ impl SerializeStruct for DynamicSerializer {
|
|||||||
|
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
return Ok(self.value);
|
return Ok(self._value);
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use crate::utils::ImmutableString;
|
|||||||
|
|
||||||
use serde::de::{Deserializer, Visitor};
|
use serde::de::{Deserializer, Visitor};
|
||||||
|
|
||||||
use crate::stdlib::any::type_name;
|
use crate::stdlib::{any::type_name, boxed::Box};
|
||||||
|
|
||||||
/// Deserializer for `ImmutableString`.
|
/// Deserializer for `ImmutableString`.
|
||||||
pub struct ImmutableStringDeserializer<'a> {
|
pub struct ImmutableStringDeserializer<'a> {
|
||||||
|
@ -245,7 +245,7 @@ fn test_module_from_ast() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.consume(r#"import "testing" as ttt; ttt::hidden()"#)
|
.consume(r#"import "testing" as ttt; ttt::hidden()"#)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "ttt::hidden"
|
EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "ttt::hidden ()"
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user