@@ -12,6 +12,7 @@ use std::{cmp, fmt};
1212use godot_ffi as sys;
1313use sys:: { ffi_methods, interface_fn, GodotFfi } ;
1414
15+ use crate :: builtin:: iter:: ArrayFunctionalOps ;
1516use crate :: builtin:: * ;
1617use crate :: meta;
1718use crate :: meta:: error:: { ConvertError , FromGodotError , FromVariantError } ;
@@ -178,7 +179,7 @@ pub struct Array<T: ArrayElement> {
178179}
179180
180181/// Guard that can only call immutable methods on the array.
181- struct ImmutableInnerArray < ' a > {
182+ pub ( super ) struct ImmutableInnerArray < ' a > {
182183 inner : inner:: InnerArray < ' a > ,
183184}
184185
@@ -608,6 +609,13 @@ impl<T: ArrayElement> Array<T> {
608609 }
609610 }
610611
612+ /// Access to Godot's functional-programming APIs based on callables.
613+ ///
614+ /// Exposes Godot array methods such as `filter()`, `map()`, `reduce()` and many more. See return type docs.
615+ pub fn functional_ops ( & self ) -> ArrayFunctionalOps < ' _ , T > {
616+ ArrayFunctionalOps :: new ( self )
617+ }
618+
611619 /// Returns the minimum value contained in the array if all elements are of comparable types.
612620 ///
613621 /// If the elements can't be compared or the array is empty, `None` is returned.
@@ -672,6 +680,8 @@ impl<T: ArrayElement> Array<T> {
672680 ///
673681 /// Calling `bsearch` on an unsorted array results in unspecified behavior. Consider using `sort()` to ensure the sorting
674682 /// order is compatible with your callable's ordering.
683+ ///
684+ /// See also: [`bsearch_by()`][Self::bsearch_by], [`functional_ops().bsearch_custom()`][ArrayFunctionalOps::bsearch_custom].
675685 pub fn bsearch ( & self , value : impl AsArg < T > ) -> usize {
676686 meta:: arg_into_ref!( value: T ) ;
677687
@@ -682,13 +692,15 @@ impl<T: ArrayElement> Array<T> {
682692 ///
683693 /// The comparator function should return an ordering that indicates whether its argument is `Less`, `Equal` or `Greater` the desired value.
684694 /// For example, for an ascending-ordered array, a simple predicate searching for a constant value would be `|elem| elem.cmp(&4)`.
685- /// See also [`slice::binary_search_by()`].
695+ /// This follows the design of [`slice::binary_search_by()`].
686696 ///
687697 /// If the value is found, returns `Ok(index)` with its index. Otherwise, returns `Err(index)`, where `index` is the insertion index
688698 /// that would maintain sorting order.
689699 ///
690- /// Calling `bsearch_by` on an unsorted array results in unspecified behavior. Consider using [`sort_by()`] to ensure
691- /// the sorting order is compatible with your callable's ordering.
700+ /// Calling `bsearch_by` on an unsorted array results in unspecified behavior. Consider using [`sort_unstable_by()`][Self::sort_unstable_by]
701+ /// to ensure the sorting order is compatible with your callable's ordering.
702+ ///
703+ /// See also: [`bsearch()`][Self::bsearch], [`functional_ops().bsearch_custom()`][ArrayFunctionalOps::bsearch_custom].
692704 pub fn bsearch_by < F > ( & self , mut func : F ) -> Result < usize , usize >
693705 where
694706 F : FnMut ( & T ) -> cmp:: Ordering + ' static ,
@@ -712,7 +724,7 @@ impl<T: ArrayElement> Array<T> {
712724
713725 let debug_name = std:: any:: type_name :: < F > ( ) ;
714726 let index = Callable :: with_scoped_fn ( debug_name, godot_comparator, |pred| {
715- self . bsearch_custom ( ignored_value, pred)
727+ self . functional_ops ( ) . bsearch_custom ( ignored_value, pred)
716728 } ) ;
717729
718730 if let Some ( value_at_index) = self . get ( index) {
@@ -724,22 +736,9 @@ impl<T: ArrayElement> Array<T> {
724736 Err ( index)
725737 }
726738
727- /// Finds the index of a value in a sorted array using binary search, with `Callable` custom predicate.
728- ///
729- /// The callable `pred` takes two elements `(a, b)` and should return if `a < b` (strictly less).
730- /// For a type-safe version, check out [`bsearch_by()`][Self::bsearch_by].
731- ///
732- /// If the value is not present in the array, returns the insertion index that would maintain sorting order.
733- ///
734- /// Calling `bsearch_custom` on an unsorted array results in unspecified behavior. Consider using `sort_custom()` to ensure
735- /// the sorting order is compatible with your callable's ordering.
739+ #[ deprecated = "Moved to `functional_ops().bsearch_custom()`" ]
736740 pub fn bsearch_custom ( & self , value : impl AsArg < T > , pred : & Callable ) -> usize {
737- meta:: arg_into_ref!( value: T ) ;
738-
739- to_usize (
740- self . as_inner ( )
741- . bsearch_custom ( & value. to_variant ( ) , pred, true ) ,
742- )
741+ self . functional_ops ( ) . bsearch_custom ( value, pred)
743742 }
744743
745744 /// Reverses the order of the elements in the array.
@@ -753,9 +752,11 @@ impl<T: ArrayElement> Array<T> {
753752 /// Sorts the array.
754753 ///
755754 /// The sorting algorithm used is not [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
756- /// This means that values considered equal may have their order changed when using `sort_unstable`. For most variant types,
755+ /// This means that values considered equal may have their order changed when using `sort_unstable() `. For most variant types,
757756 /// this distinction should not matter though.
758757 ///
758+ /// See also: [`sort_unstable_by()`][Self::sort_unstable_by], [`sort_unstable_custom()`][Self::sort_unstable_custom].
759+ ///
759760 /// _Godot equivalent: `Array.sort()`_
760761 #[ doc( alias = "sort" ) ]
761762 pub fn sort_unstable ( & mut self ) {
@@ -771,8 +772,10 @@ impl<T: ArrayElement> Array<T> {
771772 /// elements themselves would be achieved with `|a, b| a.cmp(b)`.
772773 ///
773774 /// The sorting algorithm used is not [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
774- /// This means that values considered equal may have their order changed when using `sort_unstable_by`. For most variant types,
775+ /// This means that values considered equal may have their order changed when using `sort_unstable_by() `. For most variant types,
775776 /// this distinction should not matter though.
777+ ///
778+ /// See also: [`sort_unstable()`][Self::sort_unstable], [`sort_unstable_custom()`][Self::sort_unstable_custom].
776779 pub fn sort_unstable_by < F > ( & mut self , mut func : F )
777780 where
778781 F : FnMut ( & T , & T ) -> cmp:: Ordering ,
@@ -795,14 +798,14 @@ impl<T: ArrayElement> Array<T> {
795798
796799 /// Sorts the array, using type-unsafe `Callable` comparator.
797800 ///
798- /// For a type-safe variant of this method, use [`sort_unstable_by()`][Self::sort_unstable_by].
799- ///
800801 /// The callable expects two parameters `(lhs, rhs)` and should return a bool `lhs < rhs`.
801802 ///
802803 /// The sorting algorithm used is not [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
803- /// This means that values considered equal may have their order changed when using `sort_unstable_custom`. For most variant types,
804+ /// This means that values considered equal may have their order changed when using `sort_unstable_custom()`. For most variant types,
804805 /// this distinction should not matter though.
805806 ///
807+ /// Type-safe alternatives: [`sort_unstable()`][Self::sort_unstable] , [`sort_unstable_by()`][Self::sort_unstable_by].
808+ ///
806809 /// _Godot equivalent: `Array.sort_custom()`_
807810 #[ doc( alias = "sort_custom" ) ]
808811 pub fn sort_unstable_custom ( & mut self , func : & Callable ) {
@@ -940,7 +943,7 @@ impl<T: ArrayElement> Array<T> {
940943 inner:: InnerArray :: from_outer_typed ( self )
941944 }
942945
943- fn as_inner ( & self ) -> ImmutableInnerArray < ' _ > {
946+ pub ( super ) fn as_inner ( & self ) -> ImmutableInnerArray < ' _ > {
944947 ImmutableInnerArray {
945948 // SAFETY: We can only read from the array.
946949 inner : unsafe { self . as_inner_mut ( ) } ,
@@ -1634,21 +1637,25 @@ macro_rules! varray {
16341637/// This macro creates a [slice](https://doc.rust-lang.org/std/primitive.slice.html) of `Variant` values.
16351638///
16361639/// # Examples
1637- /// Variable number of arguments:
1640+ /// ## Variable number of arguments
16381641/// ```no_run
16391642/// # use godot::prelude::*;
16401643/// let slice: &[Variant] = vslice![42, "hello", true];
1641- ///
16421644/// let concat: GString = godot::global::str(slice);
16431645/// ```
1644- /// _(In practice, you might want to use [`godot_str!`][crate::global::godot_str] instead of `str()`.) _
1646+ /// _In practice, you might want to use [`godot_str!`][crate::global::godot_str] instead of `str()`._
16451647///
1646- /// Dynamic function call via reflection. NIL can still be passed inside `vslice!`, just use `Variant::nil()`.
1648+ /// ## Dynamic function call via reflection
1649+ /// NIL can still be passed inside `vslice!`, just use `Variant::nil()`.
16471650/// ```no_run
16481651/// # use godot::prelude::*;
16491652/// # fn some_object() -> Gd<Object> { unimplemented!() }
16501653/// let mut obj: Gd<Object> = some_object();
1651- /// obj.call("some_method", vslice![Vector2i::new(1, 2), Variant::nil()]);
1654+ ///
1655+ /// obj.call("some_method", vslice![
1656+ /// Vector2i::new(1, 2),
1657+ /// Variant::nil(),
1658+ /// ]);
16521659/// ```
16531660///
16541661/// # See also
0 commit comments