Merge branch 'v1.2-fixes'
This commit is contained in:
commit
93b802effd
@ -10,6 +10,15 @@ Enhancements
|
|||||||
* Added `into_array` and `into_typed_array` for `Dynamic`.
|
* Added `into_array` and `into_typed_array` for `Dynamic`.
|
||||||
|
|
||||||
|
|
||||||
|
Version 1.2.1
|
||||||
|
=============
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Array methods (such as `map`) taking a closure with captures as argument now works properly.
|
||||||
|
|
||||||
|
|
||||||
Version 1.2.0
|
Version 1.2.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@ -252,7 +252,36 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
mapper: FnPtr,
|
mapper: FnPtr,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
map_with_fn_name(ctx, array, mapper.fn_name())
|
if array.is_empty() {
|
||||||
|
return Ok(array.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ar = Array::with_capacity(array.len());
|
||||||
|
|
||||||
|
for (i, item) in array.iter().enumerate() {
|
||||||
|
ar.push(
|
||||||
|
mapper
|
||||||
|
.call_dynamic(&ctx, None, [item.clone()])
|
||||||
|
.or_else(|err| match *err {
|
||||||
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
|
if fn_sig.starts_with(mapper.fn_name()) =>
|
||||||
|
{
|
||||||
|
mapper.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
|
}
|
||||||
|
_ => Err(err),
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
|
"map".to_string(),
|
||||||
|
ctx.source().unwrap_or("").to_string(),
|
||||||
|
err,
|
||||||
|
Position::NONE,
|
||||||
|
))
|
||||||
|
})?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ar)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "map", return_raw, pure)]
|
#[rhai_fn(name = "map", return_raw, pure)]
|
||||||
pub fn map_with_fn_name(
|
pub fn map_with_fn_name(
|
||||||
@ -260,94 +289,57 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
mapper: &str,
|
mapper: &str,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
map(ctx, array, FnPtr::new(mapper)?)
|
||||||
return Ok(Array::new());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ar = Array::with_capacity(array.len());
|
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
|
||||||
let mut args = [item, &mut index_val];
|
|
||||||
|
|
||||||
ar.push(match ctx.call_fn_raw(mapper, true, false, &mut args[..1]) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
|
||||||
if fn_sig.starts_with(mapper) =>
|
|
||||||
{
|
|
||||||
*args[1] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(mapper, true, false, &mut args)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
|
||||||
"map".to_string(),
|
|
||||||
ctx.source().unwrap_or("").to_string(),
|
|
||||||
err,
|
|
||||||
Position::NONE,
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(ar)
|
|
||||||
}
|
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw, pure)]
|
||||||
pub fn filter(
|
pub fn filter(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
|
||||||
filter_with_fn_name(ctx, array, filter.fn_name())
|
|
||||||
}
|
|
||||||
#[rhai_fn(name = "filter", return_raw, pure)]
|
|
||||||
pub fn filter_with_fn_name(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
filter: &str,
|
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
if array.is_empty() {
|
||||||
return Ok(array.clone());
|
return Ok(array.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ar = Array::new();
|
let mut ar = Array::new();
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
for (i, item) in array.iter().enumerate() {
|
||||||
let mut args = [item, &mut index_val];
|
if filter
|
||||||
|
.call_dynamic(&ctx, None, [item.clone()])
|
||||||
let keep = match ctx.call_fn_raw(filter, true, false, &mut args[..1]) {
|
.or_else(|err| match *err {
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
*args[1] = Dynamic::from(i as INT);
|
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
ctx.call_fn_raw(filter, true, false, &mut args)?
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(err),
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
"filter".to_string(),
|
"filter".to_string(),
|
||||||
ctx.source().unwrap_or("").to_string(),
|
ctx.source().unwrap_or("").to_string(),
|
||||||
err,
|
err,
|
||||||
Position::NONE,
|
Position::NONE,
|
||||||
)
|
))
|
||||||
.into())
|
})?
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.unwrap_or(false);
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
if keep {
|
ar.push(item.clone());
|
||||||
ar.push(args[0].clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ar)
|
Ok(ar)
|
||||||
}
|
}
|
||||||
|
#[rhai_fn(name = "filter", return_raw, pure)]
|
||||||
|
pub fn filter_with_fn_name(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
filter_func: &str,
|
||||||
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
|
filter(ctx, array, FnPtr::new(filter_func)?)
|
||||||
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw, pure)]
|
||||||
pub fn contains(
|
pub fn contains(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
@ -468,15 +460,6 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
start: INT,
|
start: INT,
|
||||||
) -> Result<INT, Box<EvalAltResult>> {
|
|
||||||
index_of_with_fn_name_filter_starting_from(ctx, array, filter.fn_name(), start)
|
|
||||||
}
|
|
||||||
#[rhai_fn(name = "index_of", return_raw, pure)]
|
|
||||||
pub fn index_of_with_fn_name_filter_starting_from(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
filter: &str,
|
|
||||||
start: INT,
|
|
||||||
) -> Result<INT, Box<EvalAltResult>> {
|
) -> Result<INT, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
if array.is_empty() {
|
||||||
return Ok(-1);
|
return Ok(-1);
|
||||||
@ -493,48 +476,80 @@ mod array_functions {
|
|||||||
start as usize
|
start as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut index_val = Dynamic::UNIT;
|
for (i, item) in array.iter().enumerate().skip(start) {
|
||||||
|
if filter
|
||||||
for (i, item) in array.iter_mut().enumerate().skip(start) {
|
.call_dynamic(&ctx, None, [item.clone()])
|
||||||
let mut args = [item, &mut index_val];
|
.or_else(|err| match *err {
|
||||||
|
|
||||||
let found = match ctx.call_fn_raw(filter, true, false, &mut args[..1]) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
*args[1] = Dynamic::from(i as INT);
|
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
ctx.call_fn_raw(filter, true, false, &mut args)?
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(err),
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
"index_of".to_string(),
|
"index_of".to_string(),
|
||||||
ctx.source().unwrap_or("").to_string(),
|
ctx.source().unwrap_or("").to_string(),
|
||||||
err,
|
err,
|
||||||
Position::NONE,
|
Position::NONE,
|
||||||
)
|
))
|
||||||
.into())
|
})?
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.unwrap_or(false);
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
if found {
|
|
||||||
return Ok(i as INT);
|
return Ok(i as INT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(-1 as INT)
|
Ok(-1 as INT)
|
||||||
}
|
}
|
||||||
|
#[rhai_fn(name = "index_of", return_raw, pure)]
|
||||||
|
pub fn index_of_with_fn_name_filter_starting_from(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
filter: &str,
|
||||||
|
start: INT,
|
||||||
|
) -> Result<INT, Box<EvalAltResult>> {
|
||||||
|
index_of_filter_starting_from(ctx, array, FnPtr::new(filter)?, start)
|
||||||
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw, pure)]
|
||||||
pub fn some(
|
pub fn some(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<bool, Box<EvalAltResult>> {
|
) -> Result<bool, Box<EvalAltResult>> {
|
||||||
some_with_fn_name(ctx, array, filter.fn_name())
|
if array.is_empty() {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, item) in array.iter().enumerate() {
|
||||||
|
if filter
|
||||||
|
.call_dynamic(&ctx, None, [item.clone()])
|
||||||
|
.or_else(|err| match *err {
|
||||||
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
|
{
|
||||||
|
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
|
}
|
||||||
|
_ => Err(err),
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
|
"some".to_string(),
|
||||||
|
ctx.source().unwrap_or("").to_string(),
|
||||||
|
err,
|
||||||
|
Position::NONE,
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
.as_bool()
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "some", return_raw, pure)]
|
#[rhai_fn(name = "some", return_raw, pure)]
|
||||||
pub fn some_with_fn_name(
|
pub fn some_with_fn_name(
|
||||||
@ -542,44 +557,7 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
) -> Result<bool, Box<EvalAltResult>> {
|
) -> Result<bool, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
some(ctx, array, FnPtr::new(filter)?)
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
|
||||||
let mut args = [item, &mut index_val];
|
|
||||||
|
|
||||||
let found = match ctx.call_fn_raw(filter, true, false, &mut args[..1]) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
|
||||||
if fn_sig.starts_with(filter) =>
|
|
||||||
{
|
|
||||||
*args[1] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(filter, true, false, &mut args)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
|
||||||
"some".to_string(),
|
|
||||||
ctx.source().unwrap_or("").to_string(),
|
|
||||||
err,
|
|
||||||
Position::NONE,
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.as_bool()
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if found {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(false)
|
|
||||||
}
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw, pure)]
|
||||||
pub fn all(
|
pub fn all(
|
||||||
@ -587,7 +565,37 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<bool, Box<EvalAltResult>> {
|
) -> Result<bool, Box<EvalAltResult>> {
|
||||||
all_with_fn_name(ctx, array, filter.fn_name())
|
if array.is_empty() {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, item) in array.iter().enumerate() {
|
||||||
|
if !filter
|
||||||
|
.call_dynamic(&ctx, None, [item.clone()])
|
||||||
|
.or_else(|err| match *err {
|
||||||
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
|
{
|
||||||
|
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
|
}
|
||||||
|
_ => Err(err),
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
|
"all".to_string(),
|
||||||
|
ctx.source().unwrap_or("").to_string(),
|
||||||
|
err,
|
||||||
|
Position::NONE,
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
.as_bool()
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "all", return_raw, pure)]
|
#[rhai_fn(name = "all", return_raw, pure)]
|
||||||
pub fn all_with_fn_name(
|
pub fn all_with_fn_name(
|
||||||
@ -595,44 +603,7 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
) -> Result<bool, Box<EvalAltResult>> {
|
) -> Result<bool, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
all(ctx, array, FnPtr::new(filter)?)
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
|
||||||
let mut args = [item, &mut index_val];
|
|
||||||
|
|
||||||
let found = match ctx.call_fn_raw(filter, true, false, &mut args[..1]) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
|
||||||
if fn_sig.starts_with(filter) =>
|
|
||||||
{
|
|
||||||
*args[1] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(filter, true, false, &mut args)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
|
||||||
"all".to_string(),
|
|
||||||
ctx.source().unwrap_or("").to_string(),
|
|
||||||
err,
|
|
||||||
Position::NONE,
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.as_bool()
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if !found {
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn dedup(ctx: NativeCallContext, array: &mut Array) -> Result<(), Box<EvalAltResult>> {
|
pub fn dedup(ctx: NativeCallContext, array: &mut Array) -> Result<(), Box<EvalAltResult>> {
|
||||||
@ -643,23 +614,14 @@ mod array_functions {
|
|||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
comparer: FnPtr,
|
comparer: FnPtr,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
|
||||||
dedup_with_fn_name(ctx, array, comparer.fn_name())
|
|
||||||
}
|
|
||||||
#[rhai_fn(name = "dedup", return_raw)]
|
|
||||||
fn dedup_with_fn_name(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
comparer: &str,
|
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
if array.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
array.dedup_by(|x, y| {
|
array.dedup_by(|x, y| {
|
||||||
let mut args = [x, &mut y.clone()];
|
comparer
|
||||||
|
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
||||||
ctx.call_fn_raw(comparer, true, false, &mut args)
|
|
||||||
.unwrap_or_else(|_| Dynamic::FALSE)
|
.unwrap_or_else(|_| Dynamic::FALSE)
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
@ -667,13 +629,21 @@ mod array_functions {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[rhai_fn(name = "dedup", return_raw)]
|
||||||
|
fn dedup_with_fn_name(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
comparer: &str,
|
||||||
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
|
dedup_by_comparer(ctx, array, FnPtr::new(comparer)?)
|
||||||
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw, pure)]
|
||||||
pub fn reduce(
|
pub fn reduce(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
reduce_with_fn_name(ctx, array, reducer.fn_name())
|
reduce_with_initial(ctx, array, reducer, Dynamic::UNIT)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "reduce", return_raw, pure)]
|
#[rhai_fn(name = "reduce", return_raw, pure)]
|
||||||
pub fn reduce_with_fn_name(
|
pub fn reduce_with_fn_name(
|
||||||
@ -681,7 +651,7 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
reducer: &str,
|
reducer: &str,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
reduce_with_fn_name_with_initial(ctx, array, reducer, Dynamic::UNIT)
|
reduce(ctx, array, FnPtr::new(reducer)?)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "reduce", return_raw, pure)]
|
#[rhai_fn(name = "reduce", return_raw, pure)]
|
||||||
pub fn reduce_with_initial(
|
pub fn reduce_with_initial(
|
||||||
@ -689,35 +659,23 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
initial: Dynamic,
|
initial: Dynamic,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
||||||
reduce_with_fn_name_with_initial(ctx, array, reducer.fn_name(), initial)
|
|
||||||
}
|
|
||||||
#[rhai_fn(name = "reduce", return_raw, pure)]
|
|
||||||
pub fn reduce_with_fn_name_with_initial(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
reducer: &str,
|
|
||||||
initial: Dynamic,
|
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
if array.is_empty() {
|
||||||
return Ok(initial);
|
return Ok(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = initial;
|
let mut result = initial;
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
for (i, item) in array.iter().enumerate() {
|
||||||
let mut args = [&mut result, &mut item.clone(), &mut index_val];
|
let item = item.clone();
|
||||||
|
|
||||||
result = ctx
|
result = reducer
|
||||||
.call_fn_raw(reducer, true, false, &mut args[..2])
|
.call_dynamic(&ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
*args[1] = item.clone();
|
reducer.call_dynamic(&ctx, None, [result, item, (i as INT).into()])
|
||||||
*args[2] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(reducer, true, false, &mut args)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -733,13 +691,22 @@ mod array_functions {
|
|||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
#[rhai_fn(name = "reduce", return_raw, pure)]
|
||||||
|
pub fn reduce_with_fn_name_with_initial(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
reducer: &str,
|
||||||
|
initial: Dynamic,
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
reduce_with_initial(ctx, array, FnPtr::new(reducer)?, initial)
|
||||||
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw, pure)]
|
||||||
pub fn reduce_rev(
|
pub fn reduce_rev(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
reduce_rev_with_fn_name(ctx, array, reducer.fn_name())
|
reduce_rev_with_initial(ctx, array, reducer, Dynamic::UNIT)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
|
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
|
||||||
pub fn reduce_rev_with_fn_name(
|
pub fn reduce_rev_with_fn_name(
|
||||||
@ -747,7 +714,7 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
reducer: &str,
|
reducer: &str,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
reduce_rev_with_fn_name_with_initial(ctx, array, reducer, Dynamic::UNIT)
|
reduce_rev(ctx, array, FnPtr::new(reducer)?)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
|
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
|
||||||
pub fn reduce_rev_with_initial(
|
pub fn reduce_rev_with_initial(
|
||||||
@ -755,35 +722,23 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
initial: Dynamic,
|
initial: Dynamic,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
||||||
reduce_rev_with_fn_name_with_initial(ctx, array, reducer.fn_name(), initial)
|
|
||||||
}
|
|
||||||
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
|
|
||||||
pub fn reduce_rev_with_fn_name_with_initial(
|
|
||||||
ctx: NativeCallContext,
|
|
||||||
array: &mut Array,
|
|
||||||
reducer: &str,
|
|
||||||
initial: Dynamic,
|
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
if array.is_empty() {
|
||||||
return Ok(initial);
|
return Ok(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = initial;
|
let mut result = initial;
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate().rev() {
|
for (i, item) in array.iter().enumerate().rev() {
|
||||||
let mut args = [&mut result, &mut item.clone(), &mut index_val];
|
let item = item.clone();
|
||||||
|
|
||||||
result = ctx
|
result = reducer
|
||||||
.call_fn_raw(reducer, true, false, &mut args[..2])
|
.call_dynamic(&ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
*args[1] = item.clone();
|
reducer.call_dynamic(&ctx, None, [result, item, (i as INT).into()])
|
||||||
*args[2] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(reducer, true, false, &mut args)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -799,6 +754,15 @@ mod array_functions {
|
|||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
|
||||||
|
pub fn reduce_rev_with_fn_name_with_initial(
|
||||||
|
ctx: NativeCallContext,
|
||||||
|
array: &mut Array,
|
||||||
|
reducer: &str,
|
||||||
|
initial: Dynamic,
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
reduce_rev_with_initial(ctx, array, FnPtr::new(reducer)?, initial)
|
||||||
|
}
|
||||||
#[rhai_fn(name = "sort", return_raw)]
|
#[rhai_fn(name = "sort", return_raw)]
|
||||||
pub fn sort_with_fn_name(
|
pub fn sort_with_fn_name(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
@ -905,13 +869,52 @@ mod array_functions {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn drain(
|
pub fn drain(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
drain_with_fn_name(ctx, array, filter.fn_name())
|
if array.is_empty() {
|
||||||
|
return Ok(Array::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut drained = Array::with_capacity(array.len());
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
let mut x = 0;
|
||||||
|
|
||||||
|
while x < array.len() {
|
||||||
|
if filter
|
||||||
|
.call_dynamic(&ctx, None, [array[x].clone()])
|
||||||
|
.or_else(|err| match *err {
|
||||||
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
|
{
|
||||||
|
filter.call_dynamic(&ctx, None, [array[x].clone(), (i as INT).into()])
|
||||||
|
}
|
||||||
|
_ => Err(err),
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
|
"drain".to_string(),
|
||||||
|
ctx.source().unwrap_or("").to_string(),
|
||||||
|
err,
|
||||||
|
Position::NONE,
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
.as_bool()
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
drained.push(array.remove(x));
|
||||||
|
} else {
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(drained)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "drain", return_raw)]
|
#[rhai_fn(name = "drain", return_raw)]
|
||||||
pub fn drain_with_fn_name(
|
pub fn drain_with_fn_name(
|
||||||
@ -919,65 +922,7 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
drain(ctx, array, FnPtr::new(filter)?)
|
||||||
return Ok(Array::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
let mut removed = Vec::with_capacity(array.len());
|
|
||||||
let mut count = 0;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
|
||||||
let mut args = [item, &mut index_val];
|
|
||||||
|
|
||||||
let remove = match ctx.call_fn_raw(filter, true, false, &mut args[..1]) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
|
||||||
if fn_sig.starts_with(filter) =>
|
|
||||||
{
|
|
||||||
*args[1] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(filter, true, false, &mut args)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
|
||||||
"drain".to_string(),
|
|
||||||
ctx.source().unwrap_or("").to_string(),
|
|
||||||
err,
|
|
||||||
Position::NONE,
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.as_bool()
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
removed.push(remove);
|
|
||||||
|
|
||||||
if remove {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if count == 0 {
|
|
||||||
return Ok(Array::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut result = Vec::with_capacity(count);
|
|
||||||
let mut x = 0;
|
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
while i < array.len() {
|
|
||||||
if removed[x] {
|
|
||||||
result.push(array.remove(i));
|
|
||||||
} else {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
x += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result.into())
|
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "drain")]
|
#[rhai_fn(name = "drain")]
|
||||||
pub fn drain_range(array: &mut Array, start: INT, len: INT) -> Array {
|
pub fn drain_range(array: &mut Array, start: INT, len: INT) -> Array {
|
||||||
@ -1006,13 +951,52 @@ mod array_functions {
|
|||||||
|
|
||||||
array.drain(start..start + len).collect()
|
array.drain(start..start + len).collect()
|
||||||
}
|
}
|
||||||
#[rhai_fn(return_raw, pure)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn retain(
|
pub fn retain(
|
||||||
ctx: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
retain_with_fn_name(ctx, array, filter.fn_name())
|
if array.is_empty() {
|
||||||
|
return Ok(Array::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut drained = Array::new();
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
let mut x = 0;
|
||||||
|
|
||||||
|
while x < array.len() {
|
||||||
|
if !filter
|
||||||
|
.call_dynamic(&ctx, None, [array[x].clone()])
|
||||||
|
.or_else(|err| match *err {
|
||||||
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
|
{
|
||||||
|
filter.call_dynamic(&ctx, None, [array[x].clone(), (i as INT).into()])
|
||||||
|
}
|
||||||
|
_ => Err(err),
|
||||||
|
})
|
||||||
|
.map_err(|err| {
|
||||||
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
|
"retain".to_string(),
|
||||||
|
ctx.source().unwrap_or("").to_string(),
|
||||||
|
err,
|
||||||
|
Position::NONE,
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
.as_bool()
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
drained.push(array.remove(x));
|
||||||
|
} else {
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(drained)
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "retain", return_raw)]
|
#[rhai_fn(name = "retain", return_raw)]
|
||||||
pub fn retain_with_fn_name(
|
pub fn retain_with_fn_name(
|
||||||
@ -1020,65 +1004,7 @@ mod array_functions {
|
|||||||
array: &mut Array,
|
array: &mut Array,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
) -> Result<Array, Box<EvalAltResult>> {
|
) -> Result<Array, Box<EvalAltResult>> {
|
||||||
if array.is_empty() {
|
retain(ctx, array, FnPtr::new(filter)?)
|
||||||
return Ok(Array::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut index_val = Dynamic::UNIT;
|
|
||||||
let mut removed = Vec::with_capacity(array.len());
|
|
||||||
let mut count = 0;
|
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
|
||||||
let mut args = [item, &mut index_val];
|
|
||||||
|
|
||||||
let keep = match ctx.call_fn_raw(filter, true, false, &mut args[..1]) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(err) => match *err {
|
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
|
||||||
if fn_sig.starts_with(filter) =>
|
|
||||||
{
|
|
||||||
*args[1] = Dynamic::from(i as INT);
|
|
||||||
ctx.call_fn_raw(filter, true, false, &mut args)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(EvalAltResult::ErrorInFunctionCall(
|
|
||||||
"retain".to_string(),
|
|
||||||
ctx.source().unwrap_or("").to_string(),
|
|
||||||
err,
|
|
||||||
Position::NONE,
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.as_bool()
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
removed.push(!keep);
|
|
||||||
|
|
||||||
if !keep {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if count == 0 {
|
|
||||||
return Ok(Array::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut result = Vec::with_capacity(count);
|
|
||||||
let mut x = 0;
|
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
while i < array.len() {
|
|
||||||
if removed[x] {
|
|
||||||
result.push(array.remove(i));
|
|
||||||
} else {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
x += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result.into())
|
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "retain")]
|
#[rhai_fn(name = "retain")]
|
||||||
pub fn retain_range(array: &mut Array, start: INT, len: INT) -> Array {
|
pub fn retain_range(array: &mut Array, start: INT, len: INT) -> Array {
|
||||||
|
Loading…
Reference in New Issue
Block a user