@@ -57,3 +57,45 @@ pub(crate) fn string_from_slice(slice: &[u8], range: Range<usize>) -> Result<&st
5757 str:: from_utf8 ( slice_from_slice ( slice, range) ?)
5858 . map_err ( |_| ArrowError :: InvalidArgumentError ( "invalid UTF-8 string" . to_string ( ) ) )
5959}
60+
61+ /// Performs a binary search on a slice using a fallible key extraction function.
62+ ///
63+ /// This is similar to the standard library's `binary_search_by`, but allows the key
64+ /// extraction function to fail. If key extraction fails during the search, that error
65+ /// is propagated immediately.
66+ ///
67+ /// # Arguments
68+ /// * `slice` - The slice to search in
69+ /// * `target` - The target value to search for
70+ /// * `key_extractor` - A function that extracts a comparable key from slice elements.
71+ /// This function can fail and return an error.
72+ ///
73+ /// # Returns
74+ /// * `Ok(Ok(index))` - Element found at the given index
75+ /// * `Ok(Err(index))` - Element not found, but would be inserted at the given index
76+ /// * `Err(e)` - Key extraction failed with error `e`
77+ pub ( crate ) fn try_binary_search_by < T , K , E , F > (
78+ slice : & [ T ] ,
79+ target : & K ,
80+ mut key_extractor : F ,
81+ ) -> Result < Result < usize , usize > , E >
82+ where
83+ K : Ord ,
84+ F : FnMut ( & T ) -> Result < K , E > ,
85+ {
86+ let mut left = 0 ;
87+ let mut right = slice. len ( ) ;
88+
89+ while left < right {
90+ let mid = ( left + right) / 2 ;
91+ let key = key_extractor ( & slice[ mid] ) ?;
92+
93+ match key. cmp ( target) {
94+ std:: cmp:: Ordering :: Equal => return Ok ( Ok ( mid) ) ,
95+ std:: cmp:: Ordering :: Greater => right = mid,
96+ std:: cmp:: Ordering :: Less => left = mid + 1 ,
97+ }
98+ }
99+
100+ Ok ( Err ( left) )
101+ }
0 commit comments