Deprecate array methods that take function names as parameters.

This commit is contained in:
Stephen Chung 2022-12-19 22:42:21 +08:00
parent b880893154
commit cabab14475
3 changed files with 594 additions and 512 deletions

View File

@ -22,6 +22,7 @@ Deprecated API's
* `Module::with_capacity` is deprecated. * `Module::with_capacity` is deprecated.
* The internal method `Engine::eval_statements_raw` is deprecated. * The internal method `Engine::eval_statements_raw` is deprecated.
* Array overloaded methods that take function names (as string) are deprecated in favor of using the `Fn("...")` call.
Speed improvements Speed improvements
------------------ ------------------

View File

@ -1,6 +1,7 @@
//! Module containing all deprecated API that will be removed in the next major version. //! Module containing all deprecated API that will be removed in the next major version.
use crate::func::RegisterNativeFunction; use crate::func::RegisterNativeFunction;
use crate::plugin::*;
use crate::types::dynamic::Variant; use crate::types::dynamic::Variant;
use crate::{ use crate::{
Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, NativeCallContext, Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, NativeCallContext,
@ -631,3 +632,593 @@ impl Module {
Self::new() Self::new()
} }
} }
#[cfg(not(feature = "no_index"))]
#[export_module]
pub mod deprecated_array_functions {
use crate::packages::array_basic::array_functions::*;
use crate::{Array, INT};
/// Iterate through all the elements in the array, applying a function named by `mapper` to each
/// element in turn, and return the results as a new array.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.map(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `mapper` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn square(x) { x * x }
///
/// fn multiply(x, i) { x * i }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.map("square");
///
/// print(y); // prints "[1, 4, 9, 16, 25]"
///
/// let y = x.map("multiply");
///
/// print(y); // prints "[0, 2, 6, 12, 20]"
/// ```
#[rhai_fn(name = "map", return_raw)]
pub fn map_by_fn_name(
ctx: NativeCallContext,
array: Array,
mapper: &str,
) -> RhaiResultOf<Array> {
map(ctx, array, FnPtr::new(mapper)?)
}
/// Iterate through all the elements in the array, applying a function named by `filter` to each
/// element in turn, and return a copy of all elements (in order) that return `true` as a new array.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.filter(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn screen(x, i) { x * i >= 10 }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.filter("is_odd");
///
/// print(y); // prints "[1, 3, 5]"
///
/// let y = x.filter("screen");
///
/// print(y); // prints "[12, 20]"
/// ```
#[rhai_fn(name = "filter", return_raw)]
pub fn filter_by_fn_name(
ctx: NativeCallContext,
array: Array,
filter_func: &str,
) -> RhaiResultOf<Array> {
filter(ctx, array, FnPtr::new(filter_func)?)
}
/// Iterate through all the elements in the array, applying a function named by `filter` to each
/// element in turn, and return the index of the first element that returns `true`.
/// If no element returns `true`, `-1` is returned.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.index_of(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn is_special(x) { x > 3 }
///
/// fn is_dumb(x) { x > 8 }
///
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.index_of("is_special")); // prints 3
///
/// print(x.index_of("is_dumb")); // prints -1
/// ```
#[rhai_fn(name = "index_of", return_raw, pure)]
pub fn index_of_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<INT> {
index_of_filter(ctx, array, FnPtr::new(filter)?)
}
/// Iterate through all the elements in the array, starting from a particular `start` position,
/// applying a function named by `filter` to each element in turn, and return the index of the
/// first element that returns `true`. If no element returns `true`, `-1` is returned.
///
/// * If `start` < 0, position counts from the end of the array (`-1` is the last element).
/// * If `start` < -length of array, position counts from the beginning of the array.
/// * If `start` ≥ length of array, `-1` is returned.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.index_of(Fn("fn_name"), start)` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn plural(x) { x > 1 }
///
/// fn singular(x) { x < 2 }
///
/// fn screen(x, i) { x * i > 20 }
///
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.index_of("plural", 3)); // prints 5: 2 > 1
///
/// print(x.index_of("singular", 9)); // prints -1: nothing < 2 past index 9
///
/// print(x.index_of("plural", 15)); // prints -1: nothing found past end of array
///
/// print(x.index_of("plural", -5)); // prints 9: -5 = start from index 8
///
/// print(x.index_of("plural", -99)); // prints 1: -99 = start from beginning
///
/// print(x.index_of("screen", 8)); // prints 10: 3 * 10 > 20
/// ```
#[rhai_fn(name = "index_of", return_raw, pure)]
pub fn index_of_by_fn_name_starting_from(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
start: INT,
) -> RhaiResultOf<INT> {
index_of_filter_starting_from(ctx, array, FnPtr::new(filter)?, start)
}
/// Return `true` if any element in the array that returns `true` when applied a function named
/// by `filter`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.some(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn large(x) { x > 3 }
///
/// fn huge(x) { x > 10 }
///
/// fn screen(x, i) { i > x }
///
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.some("large")); // prints true
///
/// print(x.some("huge")); // prints false
///
/// print(x.some("screen")); // prints true
/// ```
#[rhai_fn(name = "some", return_raw, pure)]
pub fn some_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<bool> {
some(ctx, array, FnPtr::new(filter)?)
}
/// Return `true` if all elements in the array return `true` when applied a function named by `filter`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.all(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.all(|v| v > 3)); // prints false
///
/// print(x.all(|v| v > 1)); // prints true
///
/// print(x.all(|v, i| i > v)); // prints false
/// ```
#[rhai_fn(name = "all", return_raw, pure)]
pub fn all_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<bool> {
all(ctx, array, FnPtr::new(filter)?)
}
/// Remove duplicated _consecutive_ elements from the array that return `true` when applied a
/// function named by `comparer`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.dedup(Fn("fn_name"))` instead.
///
/// No element is removed if the correct `comparer` function does not exist.
///
/// # Function Parameters
///
/// * `element1`: copy of the current array element to compare
/// * `element2`: copy of the next array element to compare
///
/// ## Return Value
///
/// `true` if `element1 == element2`, otherwise `false`.
///
/// # Example
///
/// ```rhai
/// fn declining(a, b) { a >= b }
///
/// let x = [1, 2, 2, 2, 3, 1, 2, 3, 4, 3, 3, 2, 1];
///
/// x.dedup("declining");
///
/// print(x); // prints "[1, 2, 3, 4]"
/// ```
#[rhai_fn(name = "dedup", return_raw)]
pub fn dedup_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
comparer: &str,
) -> RhaiResultOf<()> {
Ok(dedup_by_comparer(ctx, array, FnPtr::new(comparer)?))
}
/// Reduce an array by iterating through all elements while applying a function named by `reducer`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.reduce(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, initially `()`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) {
/// x + (r ?? 0)
/// }
/// fn process_extra(r, x, i) {
/// x + i + (r ?? 0)
/// }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce("process");
///
/// print(y); // prints 15
///
/// let y = x.reduce("process_extra");
///
/// print(y); // prints 25
/// ```
#[rhai_fn(name = "reduce", return_raw, pure)]
pub fn reduce_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
) -> RhaiResult {
reduce(ctx, array, FnPtr::new(reducer)?)
}
/// Reduce an array by iterating through all elements while applying a function named by `reducer`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.reduce(Fn("fn_name"), initial)` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, starting with the value of `initial`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) { x + r }
///
/// fn process_extra(r, x, i) { x + i + r }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce("process", 5);
///
/// print(y); // prints 20
///
/// let y = x.reduce("process_extra", 5);
///
/// print(y); // prints 30
/// ```
#[rhai_fn(name = "reduce", return_raw, pure)]
pub fn reduce_by_fn_name_with_initial(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
initial: Dynamic,
) -> RhaiResult {
reduce_with_initial(ctx, array, FnPtr::new(reducer)?, initial)
}
/// Reduce an array by iterating through all elements, in _reverse_ order,
/// while applying a function named by `reducer`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.reduce_rev(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, initially `()`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) {
/// x + (r ?? 0)
/// }
/// fn process_extra(r, x, i) {
/// x + i + (r ?? 0)
/// }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce_rev("process");
///
/// print(y); // prints 15
///
/// let y = x.reduce_rev("process_extra");
///
/// print(y); // prints 25
/// ```
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
pub fn reduce_rev_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
) -> RhaiResult {
reduce_rev(ctx, array, FnPtr::new(reducer)?)
}
/// Reduce an array by iterating through all elements, in _reverse_ order,
/// while applying a function named by `reducer`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.reduce_rev(Fn("fn_name"), initial)` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, starting with the value of `initial`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) { x + r }
///
/// fn process_extra(r, x, i) { x + i + r }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce_rev("process", 5);
///
/// print(y); // prints 20
///
/// let y = x.reduce_rev("process_extra", 5);
///
/// print(y); // prints 30
/// ```
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
pub fn reduce_rev_by_fn_name_with_initial(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
initial: Dynamic,
) -> RhaiResult {
reduce_rev_with_initial(ctx, array, FnPtr::new(reducer)?, initial)
}
/// Sort the array based on applying a function named by `comparer`.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.sort(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `comparer` must exist taking these parameters:
///
/// * `element1`: copy of the current array element to compare
/// * `element2`: copy of the next array element to compare
///
/// ## Return Value
///
/// * Any integer > 0 if `element1 > element2`
/// * Zero if `element1 == element2`
/// * Any integer < 0 if `element1 < element2`
///
/// # Example
///
/// ```rhai
/// fn reverse(a, b) {
/// if a > b {
/// -1
/// } else if a < b {
/// 1
/// } else {
/// 0
/// }
/// }
/// let x = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10];
///
/// x.sort("reverse");
///
/// print(x); // prints "[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]"
/// ```
#[rhai_fn(name = "sort", return_raw)]
pub fn sort_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
comparer: &str,
) -> RhaiResultOf<()> {
sort(ctx, array, FnPtr::new(comparer)?)
}
/// Remove all elements in the array that returns `true` when applied a function named by `filter`
/// and return them as a new array.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.drain(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn small(x) { x < 3 }
///
/// fn screen(x, i) { x + i > 5 }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.drain("small");
///
/// print(x); // prints "[3, 4, 5]"
///
/// print(y); // prints "[1, 2]"
///
/// let z = x.drain("screen");
///
/// print(x); // prints "[3, 4]"
///
/// print(z); // prints "[5]"
/// ```
#[rhai_fn(name = "drain", return_raw)]
pub fn drain_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<Array> {
drain(ctx, array, FnPtr::new(filter)?)
}
/// Remove all elements in the array that do not return `true` when applied a function named by
/// `filter` and return them as a new array.
///
/// # Deprecated API
///
/// This method is deprecated and will be removed from the next major version.
/// Use `array.retain(Fn("fn_name"))` instead.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn large(x) { x >= 3 }
///
/// fn screen(x, i) { x + i <= 5 }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.retain("large");
///
/// print(x); // prints "[3, 4, 5]"
///
/// print(y); // prints "[1, 2]"
///
/// let z = x.retain("screen");
///
/// print(x); // prints "[3, 4]"
///
/// print(z); // prints "[5]"
/// ```
#[rhai_fn(name = "retain", return_raw)]
pub fn retain_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<Array> {
retain(ctx, array, FnPtr::new(filter)?)
}
}

View File

@ -1,5 +1,6 @@
#![cfg(not(feature = "no_index"))] #![cfg(not(feature = "no_index"))]
use crate::api::deprecated::deprecated_array_functions;
use crate::engine::OP_EQUALS; use crate::engine::OP_EQUALS;
use crate::eval::{calc_index, calc_offset_len}; use crate::eval::{calc_index, calc_offset_len};
use crate::module::ModuleFlags; use crate::module::ModuleFlags;
@ -18,6 +19,7 @@ def_package! {
lib.flags |= ModuleFlags::STANDARD_LIB; lib.flags |= ModuleFlags::STANDARD_LIB;
combine_with_exported_module!(lib, "array", array_functions); combine_with_exported_module!(lib, "array", array_functions);
combine_with_exported_module!(lib, "deprecated_array", deprecated_array_functions);
// Register array iterator // Register array iterator
lib.set_iterable::<Array>(); lib.set_iterable::<Array>();
@ -715,41 +717,6 @@ pub mod array_functions {
Ok(ar) Ok(ar)
} }
/// Iterate through all the elements in the array, applying a function named by `mapper` to each
/// element in turn, and return the results as a new array.
///
/// # Function Parameters
///
/// A function with the same name as the value of `mapper` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn square(x) { x * x }
///
/// fn multiply(x, i) { x * i }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.map("square");
///
/// print(y); // prints "[1, 4, 9, 16, 25]"
///
/// let y = x.map("multiply");
///
/// print(y); // prints "[0, 2, 6, 12, 20]"
/// ```
#[rhai_fn(name = "map", return_raw)]
pub fn map_by_fn_name(
ctx: NativeCallContext,
array: Array,
mapper: &str,
) -> RhaiResultOf<Array> {
map(ctx, array, FnPtr::new(mapper)?)
}
/// Iterate through all the elements in the array, applying a `filter` function to each element /// Iterate through all the elements in the array, applying a `filter` function to each element
/// in turn, and return a copy of all elements (in order) that return `true` as a new array. /// in turn, and return a copy of all elements (in order) that return `true` as a new array.
@ -791,39 +758,6 @@ pub mod array_functions {
Ok(ar) Ok(ar)
} }
/// Iterate through all the elements in the array, applying a function named by `filter` to each
/// element in turn, and return a copy of all elements (in order) that return `true` as a new array.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn screen(x, i) { x * i >= 10 }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.filter("is_odd");
///
/// print(y); // prints "[1, 3, 5]"
///
/// let y = x.filter("screen");
///
/// print(y); // prints "[12, 20]"
/// ```
#[rhai_fn(name = "filter", return_raw)]
pub fn filter_by_fn_name(
ctx: NativeCallContext,
array: Array,
filter_func: &str,
) -> RhaiResultOf<Array> {
filter(ctx, array, FnPtr::new(filter_func)?)
}
/// Return `true` if the array contains an element that equals `value`. /// Return `true` if the array contains an element that equals `value`.
/// ///
/// The operator `==` is used to compare elements with `value` and must be defined, /// The operator `==` is used to compare elements with `value` and must be defined,
@ -998,38 +932,6 @@ pub mod array_functions {
index_of_filter_starting_from(ctx, array, filter, 0) index_of_filter_starting_from(ctx, array, filter, 0)
} }
} }
/// Iterate through all the elements in the array, applying a function named by `filter` to each
/// element in turn, and return the index of the first element that returns `true`.
/// If no element returns `true`, `-1` is returned.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn is_special(x) { x > 3 }
///
/// fn is_dumb(x) { x > 8 }
///
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.index_of("is_special")); // prints 3
///
/// print(x.index_of("is_dumb")); // prints -1
/// ```
#[rhai_fn(name = "index_of", return_raw, pure)]
pub fn index_of_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<INT> {
index_of_filter(ctx, array, FnPtr::new(filter)?)
}
/// Iterate through all the elements in the array, starting from a particular `start` position, /// Iterate through all the elements in the array, starting from a particular `start` position,
/// applying a `filter` function to each element in turn, and return the index of the first /// applying a `filter` function to each element in turn, and return the index of the first
/// element that returns `true`. If no element returns `true`, `-1` is returned. /// element that returns `true`. If no element returns `true`, `-1` is returned.
@ -1084,53 +986,6 @@ pub mod array_functions {
Ok(-1 as INT) Ok(-1 as INT)
} }
/// Iterate through all the elements in the array, starting from a particular `start` position,
/// applying a function named by `filter` to each element in turn, and return the index of the
/// first element that returns `true`. If no element returns `true`, `-1` is returned.
///
/// * If `start` < 0, position counts from the end of the array (`-1` is the last element).
/// * If `start` < -length of array, position counts from the beginning of the array.
/// * If `start` ≥ length of array, `-1` is returned.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn plural(x) { x > 1 }
///
/// fn singular(x) { x < 2 }
///
/// fn screen(x, i) { x * i > 20 }
///
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.index_of("plural", 3)); // prints 5: 2 > 1
///
/// print(x.index_of("singular", 9)); // prints -1: nothing < 2 past index 9
///
/// print(x.index_of("plural", 15)); // prints -1: nothing found past end of array
///
/// print(x.index_of("plural", -5)); // prints 9: -5 = start from index 8
///
/// print(x.index_of("plural", -99)); // prints 1: -99 = start from beginning
///
/// print(x.index_of("screen", 8)); // prints 10: 3 * 10 > 20
/// ```
#[rhai_fn(name = "index_of", return_raw, pure)]
pub fn index_of_by_fn_name_starting_from(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
start: INT,
) -> RhaiResultOf<INT> {
index_of_filter_starting_from(ctx, array, FnPtr::new(filter)?, start)
}
/// Return `true` if any element in the array that returns `true` when applied the `filter` function. /// Return `true` if any element in the array that returns `true` when applied the `filter` function.
/// ///
/// # Function Parameters /// # Function Parameters
@ -1166,41 +1021,6 @@ pub mod array_functions {
Ok(false) Ok(false)
} }
/// Return `true` if any element in the array that returns `true` when applied a function named
/// by `filter`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn large(x) { x > 3 }
///
/// fn huge(x) { x > 10 }
///
/// fn screen(x, i) { i > x }
///
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.some("large")); // prints true
///
/// print(x.some("huge")); // prints false
///
/// print(x.some("screen")); // prints true
/// ```
#[rhai_fn(name = "some", return_raw, pure)]
pub fn some_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<bool> {
some(ctx, array, FnPtr::new(filter)?)
}
/// Return `true` if all elements in the array return `true` when applied the `filter` function. /// Return `true` if all elements in the array return `true` when applied the `filter` function.
/// ///
/// # Function Parameters /// # Function Parameters
@ -1236,34 +1056,6 @@ pub mod array_functions {
Ok(true) Ok(true)
} }
/// Return `true` if all elements in the array return `true` when applied a function named by `filter`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// let x = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5];
///
/// print(x.all(|v| v > 3)); // prints false
///
/// print(x.all(|v| v > 1)); // prints true
///
/// print(x.all(|v, i| i > v)); // prints false
/// ```
#[rhai_fn(name = "all", return_raw, pure)]
pub fn all_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<bool> {
all(ctx, array, FnPtr::new(filter)?)
}
/// Remove duplicated _consecutive_ elements from the array. /// Remove duplicated _consecutive_ elements from the array.
/// ///
/// The operator `==` is used to compare elements and must be defined, /// The operator `==` is used to compare elements and must be defined,
@ -1319,39 +1111,6 @@ pub mod array_functions {
.unwrap_or(false) .unwrap_or(false)
}); });
} }
/// Remove duplicated _consecutive_ elements from the array that return `true` when applied a
/// function named by `comparer`.
///
/// No element is removed if the correct `comparer` function does not exist.
///
/// # Function Parameters
///
/// * `element1`: copy of the current array element to compare
/// * `element2`: copy of the next array element to compare
///
/// ## Return Value
///
/// `true` if `element1 == element2`, otherwise `false`.
///
/// # Example
///
/// ```rhai
/// fn declining(a, b) { a >= b }
///
/// let x = [1, 2, 2, 2, 3, 1, 2, 3, 4, 3, 3, 2, 1];
///
/// x.dedup("declining");
///
/// print(x); // prints "[1, 2, 3, 4]"
/// ```
#[rhai_fn(name = "dedup", return_raw)]
pub fn dedup_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
comparer: &str,
) -> RhaiResultOf<()> {
Ok(dedup_by_comparer(ctx, array, FnPtr::new(comparer)?))
}
/// Reduce an array by iterating through all elements while applying the `reducer` function. /// Reduce an array by iterating through all elements while applying the `reducer` function.
/// ///
/// # Function Parameters /// # Function Parameters
@ -1377,44 +1136,6 @@ pub mod array_functions {
pub fn reduce(ctx: NativeCallContext, array: &mut Array, reducer: FnPtr) -> RhaiResult { pub fn reduce(ctx: NativeCallContext, array: &mut Array, reducer: FnPtr) -> RhaiResult {
reduce_with_initial(ctx, array, reducer, Dynamic::UNIT) reduce_with_initial(ctx, array, reducer, Dynamic::UNIT)
} }
/// Reduce an array by iterating through all elements while applying a function named by `reducer`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, initially `()`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) {
/// x + (r ?? 0)
/// }
/// fn process_extra(r, x, i) {
/// x + i + (r ?? 0)
/// }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce("process");
///
/// print(y); // prints 15
///
/// let y = x.reduce("process_extra");
///
/// print(y); // prints 25
/// ```
#[rhai_fn(name = "reduce", return_raw, pure)]
pub fn reduce_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
) -> RhaiResult {
reduce(ctx, array, FnPtr::new(reducer)?)
}
/// Reduce an array by iterating through all elements while applying the `reducer` function. /// Reduce an array by iterating through all elements while applying the `reducer` function.
/// ///
/// # Function Parameters /// # Function Parameters
@ -1454,42 +1175,6 @@ pub mod array_functions {
make_dual_arity_fn_ptr_call("reduce", &reducer, &ctx, [result, item.clone()], i) make_dual_arity_fn_ptr_call("reduce", &reducer, &ctx, [result, item.clone()], i)
}) })
} }
/// Reduce an array by iterating through all elements while applying a function named by `reducer`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, starting with the value of `initial`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) { x + r }
///
/// fn process_extra(r, x, i) { x + i + r }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce("process", 5);
///
/// print(y); // prints 20
///
/// let y = x.reduce("process_extra", 5);
///
/// print(y); // prints 30
/// ```
#[rhai_fn(name = "reduce", return_raw, pure)]
pub fn reduce_by_fn_name_with_initial(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
initial: Dynamic,
) -> RhaiResult {
reduce_with_initial(ctx, array, FnPtr::new(reducer)?, initial)
}
/// Reduce an array by iterating through all elements, in _reverse_ order, /// Reduce an array by iterating through all elements, in _reverse_ order,
/// while applying the `reducer` function. /// while applying the `reducer` function.
/// ///
@ -1517,45 +1202,6 @@ pub mod array_functions {
reduce_rev_with_initial(ctx, array, reducer, Dynamic::UNIT) reduce_rev_with_initial(ctx, array, reducer, Dynamic::UNIT)
} }
/// Reduce an array by iterating through all elements, in _reverse_ order, /// Reduce an array by iterating through all elements, in _reverse_ order,
/// while applying a function named by `reducer`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, initially `()`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) {
/// x + (r ?? 0)
/// }
/// fn process_extra(r, x, i) {
/// x + i + (r ?? 0)
/// }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce_rev("process");
///
/// print(y); // prints 15
///
/// let y = x.reduce_rev("process_extra");
///
/// print(y); // prints 25
/// ```
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
pub fn reduce_rev_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
) -> RhaiResult {
reduce_rev(ctx, array, FnPtr::new(reducer)?)
}
/// Reduce an array by iterating through all elements, in _reverse_ order,
/// while applying the `reducer` function. /// while applying the `reducer` function.
/// ///
/// # Function Parameters /// # Function Parameters
@ -1602,43 +1248,6 @@ pub mod array_functions {
) )
}) })
} }
/// Reduce an array by iterating through all elements, in _reverse_ order,
/// while applying a function named by `reducer`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `reducer` must exist taking these parameters:
///
/// * `result`: accumulated result, starting with the value of `initial`
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn process(r, x) { x + r }
///
/// fn process_extra(r, x, i) { x + i + r }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.reduce_rev("process", 5);
///
/// print(y); // prints 20
///
/// let y = x.reduce_rev("process_extra", 5);
///
/// print(y); // prints 30
/// ```
#[rhai_fn(name = "reduce_rev", return_raw, pure)]
pub fn reduce_rev_by_fn_name_with_initial(
ctx: NativeCallContext,
array: &mut Array,
reducer: &str,
initial: Dynamic,
) -> RhaiResult {
reduce_rev_with_initial(ctx, array, FnPtr::new(reducer)?, initial)
}
/// Sort the array based on applying the `comparer` function. /// Sort the array based on applying the `comparer` function.
/// ///
/// # Function Parameters /// # Function Parameters
@ -1686,47 +1295,6 @@ pub mod array_functions {
Ok(()) Ok(())
} }
/// Sort the array based on applying a function named by `comparer`.
///
/// # Function Parameters
///
/// A function with the same name as the value of `comparer` must exist taking these parameters:
///
/// * `element1`: copy of the current array element to compare
/// * `element2`: copy of the next array element to compare
///
/// ## Return Value
///
/// * Any integer > 0 if `element1 > element2`
/// * Zero if `element1 == element2`
/// * Any integer < 0 if `element1 < element2`
///
/// # Example
///
/// ```rhai
/// fn reverse(a, b) {
/// if a > b {
/// -1
/// } else if a < b {
/// 1
/// } else {
/// 0
/// }
/// }
/// let x = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10];
///
/// x.sort("reverse");
///
/// print(x); // prints "[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]"
/// ```
#[rhai_fn(name = "sort", return_raw)]
pub fn sort_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
comparer: &str,
) -> RhaiResultOf<()> {
sort(ctx, array, FnPtr::new(comparer)?)
}
/// Sort the array. /// Sort the array.
/// ///
/// All elements in the array must be of the same data type. /// All elements in the array must be of the same data type.
@ -1873,45 +1441,6 @@ pub mod array_functions {
Ok(drained) Ok(drained)
} }
/// Remove all elements in the array that returns `true` when applied a function named by `filter`
/// and return them as a new array.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn small(x) { x < 3 }
///
/// fn screen(x, i) { x + i > 5 }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.drain("small");
///
/// print(x); // prints "[3, 4, 5]"
///
/// print(y); // prints "[1, 2]"
///
/// let z = x.drain("screen");
///
/// print(x); // prints "[3, 4]"
///
/// print(z); // prints "[5]"
/// ```
#[rhai_fn(name = "drain", return_raw)]
pub fn drain_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<Array> {
drain(ctx, array, FnPtr::new(filter)?)
}
/// Remove all elements in the array within an exclusive `range` and return them as a new array. /// Remove all elements in the array within an exclusive `range` and return them as a new array.
/// ///
/// # Example /// # Example
@ -2052,45 +1581,6 @@ pub mod array_functions {
Ok(drained) Ok(drained)
} }
/// Remove all elements in the array that do not return `true` when applied a function named by
/// `filter` and return them as a new array.
///
/// # Function Parameters
///
/// A function with the same name as the value of `filter` must exist taking these parameters:
///
/// * `element`: copy of array element
/// * `index` _(optional)_: current index in the array
///
/// # Example
///
/// ```rhai
/// fn large(x) { x >= 3 }
///
/// fn screen(x, i) { x + i <= 5 }
///
/// let x = [1, 2, 3, 4, 5];
///
/// let y = x.retain("large");
///
/// print(x); // prints "[3, 4, 5]"
///
/// print(y); // prints "[1, 2]"
///
/// let z = x.retain("screen");
///
/// print(x); // prints "[3, 4]"
///
/// print(z); // prints "[5]"
/// ```
#[rhai_fn(name = "retain", return_raw)]
pub fn retain_by_fn_name(
ctx: NativeCallContext,
array: &mut Array,
filter: &str,
) -> RhaiResultOf<Array> {
retain(ctx, array, FnPtr::new(filter)?)
}
/// Remove all elements in the array not within an exclusive `range` and return them as a new array. /// Remove all elements in the array not within an exclusive `range` and return them as a new array.
/// ///
/// # Example /// # Example