Skip to content

Commit 252eee7

Browse files
committed
Rename f_fallible and add docs
1 parent 5900bd4 commit 252eee7

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

arrow-cast/src/cast/decimal.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ impl DecimalCast for i256 {
148148
/// Construct closures to upscale decimals from `(input_precision, input_scale)` to
149149
/// `(output_precision, output_scale)`.
150150
///
151+
/// Returns `(f_fallible, f_infallible)` where:
152+
/// * `f_fallible` yields `None` when the requested cast would overflow
153+
/// * `f_infallible` is present only when every input is guaranteed to succeed; otherwise it is `None`
154+
/// and callers must fall back to `f_fallible`
155+
///
151156
/// Returns `None` if the required scale increase `delta_scale = output_scale - input_scale`
152157
/// exceeds the supported precomputed precision table `O::MAX_FOR_EACH_PRECISION`.
153158
/// In that case, the caller should treat this as an overflow for the output scale
@@ -174,7 +179,7 @@ where
174179
// handling, which is faster and simpler for scaling by 10^delta_scale.
175180
let max = O::MAX_FOR_EACH_PRECISION.get(delta_scale as usize)?;
176181
let mul = max.add_wrapping(O::Native::ONE);
177-
let f = move |x| O::Native::from_decimal(x).and_then(|x| x.mul_checked(mul).ok());
182+
let f_fallible = move |x| O::Native::from_decimal(x).and_then(|x| x.mul_checked(mul).ok());
178183

179184
// if the gain in precision (digits) is greater than the multiplication due to scaling
180185
// every number will fit into the output type
@@ -185,12 +190,17 @@ where
185190
let is_infallible_cast = (input_precision as i8) + delta_scale <= (output_precision as i8);
186191
let f_infallible = is_infallible_cast
187192
.then_some(move |x| O::Native::from_decimal(x).unwrap().mul_wrapping(mul));
188-
Some((f, f_infallible))
193+
Some((f_fallible, f_infallible))
189194
}
190195

191196
/// Construct closures to downscale decimals from `(input_precision, input_scale)` to
192197
/// `(output_precision, output_scale)`.
193198
///
199+
/// Returns `(f_fallible, f_infallible)` where:
200+
/// * `f_fallible` yields `None` when the requested cast would overflow
201+
/// * `f_infallible` is present only when every input is guaranteed to succeed; otherwise it is `None`
202+
/// and callers must fall back to `f_fallible`
203+
///
194204
/// Returns `None` if the required scale reduction `delta_scale = input_scale - output_scale`
195205
/// exceeds the supported precomputed precision table `I::MAX_FOR_EACH_PRECISION`.
196206
/// In this scenario, any value would round to zero (e.g., dividing by 10^k where k exceeds the
@@ -224,7 +234,7 @@ where
224234
let half = div.div_wrapping(I::Native::ONE.add_wrapping(I::Native::ONE));
225235
let half_neg = half.neg_wrapping();
226236

227-
let f = move |x: I::Native| {
237+
let f_fallible = move |x: I::Native| {
228238
// div is >= 10 and so this cannot overflow
229239
let d = x.div_wrapping(div);
230240
let r = x.mod_wrapping(div);
@@ -249,8 +259,8 @@ where
249259
// e.g. Decimal(5, 3) 99.999 to Decimal(3, 0) will result in 100:
250260
// [99999] -> [99] + 1 = [100], a cast to Decimal(2, 0) would not be possible
251261
let is_infallible_cast = (input_precision as i8) - delta_scale < (output_precision as i8);
252-
let f_infallible = is_infallible_cast.then_some(move |x| f(x).unwrap());
253-
Some((f, f_infallible))
262+
let f_infallible = is_infallible_cast.then_some(move |x| f_fallible(x).unwrap());
263+
Some((f_fallible, f_infallible))
254264
}
255265

256266
/// Apply the rescaler function to the value.
@@ -343,7 +353,7 @@ fn apply_decimal_cast<I: DecimalType, O: DecimalType>(
343353
array: &PrimitiveArray<I>,
344354
output_precision: u8,
345355
output_scale: i8,
346-
f: impl Fn(I::Native) -> Option<O::Native>,
356+
f_fallible: impl Fn(I::Native) -> Option<O::Native>,
347357
f_infallible: Option<impl Fn(I::Native) -> O::Native>,
348358
cast_options: &CastOptions,
349359
) -> Result<PrimitiveArray<O>, ArrowError>
@@ -354,11 +364,13 @@ where
354364
let array = if let Some(f_infallible) = f_infallible {
355365
array.unary(f_infallible)
356366
} else if cast_options.safe {
357-
array.unary_opt(|x| f(x).filter(|v| O::is_valid_decimal_precision(*v, output_precision)))
367+
array.unary_opt(|x| {
368+
f_fallible(x).filter(|v| O::is_valid_decimal_precision(*v, output_precision))
369+
})
358370
} else {
359371
let error = cast_decimal_to_decimal_error::<I, O>(output_precision, output_scale);
360372
array.try_unary(|x| {
361-
f(x).ok_or_else(|| error(x)).and_then(|v| {
373+
f_fallible(x).ok_or_else(|| error(x)).and_then(|v| {
362374
O::validate_decimal_precision(v, output_precision, output_scale).map(|_| v)
363375
})
364376
})?
@@ -380,14 +392,14 @@ where
380392
I::Native: DecimalCast + ArrowNativeTypeOp,
381393
O::Native: DecimalCast + ArrowNativeTypeOp,
382394
{
383-
if let Some((f, f_infallible)) =
395+
if let Some((f_fallible, f_infallible)) =
384396
make_downscaler::<I, O>(input_precision, input_scale, output_precision, output_scale)
385397
{
386398
apply_decimal_cast(
387399
array,
388400
output_precision,
389401
output_scale,
390-
f,
402+
f_fallible,
391403
f_infallible,
392404
cast_options,
393405
)

0 commit comments

Comments
 (0)