Skip to content

Commit 4010b73

Browse files
committed
[FIX] format code with improved iters and value::null handling
1 parent b16d1e5 commit 4010b73

File tree

1 file changed

+68
-14
lines changed

1 file changed

+68
-14
lines changed

parquet-variant/src/to_json.rs

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,13 @@ fn convert_object_to_json(buffer: &mut impl Write, obj: &VariantObject) -> Resul
207207
fn convert_array_to_json(buffer: &mut impl Write, arr: &VariantList) -> Result<(), ArrowError> {
208208
write!(buffer, "[")?;
209209

210-
let len = arr.len();
211-
for i in 0..len {
212-
if i > 0 {
210+
let mut first = true;
211+
for element in arr.iter() {
212+
if !first {
213213
write!(buffer, ",")?;
214214
}
215+
first = false;
215216

216-
let element = arr.get(i)?;
217217
variant_to_json(buffer, &element)?;
218218
}
219219

@@ -336,7 +336,7 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
336336
Variant::Int16(i) => Ok(Value::Number((*i).into())),
337337
Variant::Int32(i) => Ok(Value::Number((*i).into())),
338338
Variant::Int64(i) => Ok(Value::Number((*i).into())),
339-
Variant::Float(f) => serde_json::Number::from_f64(*f as f64)
339+
Variant::Float(f) => serde_json::Number::from_f64((*f).into())
340340
.map(Value::Number)
341341
.ok_or_else(|| ArrowError::InvalidArgumentError("Invalid float value".to_string())),
342342
Variant::Double(f) => serde_json::Number::from_f64(*f)
@@ -350,12 +350,14 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
350350
let divisor = 10_i32.pow(*scale as u32);
351351
let quotient = integer / divisor;
352352
let remainder = (integer % divisor).abs();
353-
let formatted_remainder = format!("{:0width$}", remainder, width = *scale as usize);
354-
let trimmed_remainder = formatted_remainder.trim_end_matches('0');
355353

356-
let decimal_str = if trimmed_remainder.is_empty() {
354+
let decimal_str = if remainder == 0 {
357355
quotient.to_string()
358356
} else {
357+
// The {:0width$} format ensures it correctly renders with leading zeros (e.g., .0000100)
358+
let formatted_remainder = format!("{:0width$}", remainder, width = *scale as usize);
359+
// Then strip away any trailing zeros (e.g., .00001)
360+
let trimmed_remainder = formatted_remainder.trim_end_matches('0');
359361
format!("{}.{}", quotient, trimmed_remainder)
360362
};
361363

@@ -376,12 +378,14 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
376378
let divisor = 10_i64.pow(*scale as u32);
377379
let quotient = integer / divisor;
378380
let remainder = (integer % divisor).abs();
379-
let formatted_remainder = format!("{:0width$}", remainder, width = *scale as usize);
380-
let trimmed_remainder = formatted_remainder.trim_end_matches('0');
381381

382-
let decimal_str = if trimmed_remainder.is_empty() {
382+
let decimal_str = if remainder == 0 {
383383
quotient.to_string()
384384
} else {
385+
// The {:0width$} format ensures it correctly renders with leading zeros (e.g., .0000100)
386+
let formatted_remainder = format!("{:0width$}", remainder, width = *scale as usize);
387+
// Then strip away any trailing zeros (e.g., .00001)
388+
let trimmed_remainder = formatted_remainder.trim_end_matches('0');
385389
format!("{}.{}", quotient, trimmed_remainder)
386390
};
387391

@@ -402,12 +406,14 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
402406
let divisor = 10_i128.pow(*scale as u32);
403407
let quotient = integer / divisor;
404408
let remainder = (integer % divisor).abs();
405-
let formatted_remainder = format!("{:0width$}", remainder, width = *scale as usize);
406-
let trimmed_remainder = formatted_remainder.trim_end_matches('0');
407409

408-
let decimal_str = if trimmed_remainder.is_empty() {
410+
let decimal_str = if remainder == 0 {
409411
quotient.to_string()
410412
} else {
413+
// The {:0width$} format ensures it correctly renders with leading zeros (e.g., .0000100)
414+
let formatted_remainder = format!("{:0width$}", remainder, width = *scale as usize);
415+
// Then strip away any trailing zeros (e.g., .00001)
416+
let trimmed_remainder = formatted_remainder.trim_end_matches('0');
411417
format!("{}.{}", quotient, trimmed_remainder)
412418
};
413419

@@ -1246,4 +1252,52 @@ mod tests {
12461252

12471253
Ok(())
12481254
}
1255+
1256+
#[test]
1257+
fn test_float_nan_inf_handling() -> Result<(), ArrowError> {
1258+
// Test NaN handling - should return an error since JSON doesn't support NaN
1259+
let nan_variant = Variant::Float(f32::NAN);
1260+
let nan_result = variant_to_json_value(&nan_variant);
1261+
assert!(nan_result.is_err());
1262+
assert!(nan_result.unwrap_err().to_string().contains("Invalid float value"));
1263+
1264+
// Test positive infinity - should return an error since JSON doesn't support Infinity
1265+
let pos_inf_variant = Variant::Float(f32::INFINITY);
1266+
let pos_inf_result = variant_to_json_value(&pos_inf_variant);
1267+
assert!(pos_inf_result.is_err());
1268+
assert!(pos_inf_result.unwrap_err().to_string().contains("Invalid float value"));
1269+
1270+
// Test negative infinity - should return an error since JSON doesn't support -Infinity
1271+
let neg_inf_variant = Variant::Float(f32::NEG_INFINITY);
1272+
let neg_inf_result = variant_to_json_value(&neg_inf_variant);
1273+
assert!(neg_inf_result.is_err());
1274+
assert!(neg_inf_result.unwrap_err().to_string().contains("Invalid float value"));
1275+
1276+
// Test the same for Double variants
1277+
let nan_double_variant = Variant::Double(f64::NAN);
1278+
let nan_double_result = variant_to_json_value(&nan_double_variant);
1279+
assert!(nan_double_result.is_err());
1280+
assert!(nan_double_result.unwrap_err().to_string().contains("Invalid double value"));
1281+
1282+
let pos_inf_double_variant = Variant::Double(f64::INFINITY);
1283+
let pos_inf_double_result = variant_to_json_value(&pos_inf_double_variant);
1284+
assert!(pos_inf_double_result.is_err());
1285+
assert!(pos_inf_double_result.unwrap_err().to_string().contains("Invalid double value"));
1286+
1287+
let neg_inf_double_variant = Variant::Double(f64::NEG_INFINITY);
1288+
let neg_inf_double_result = variant_to_json_value(&neg_inf_double_variant);
1289+
assert!(neg_inf_double_result.is_err());
1290+
assert!(neg_inf_double_result.unwrap_err().to_string().contains("Invalid double value"));
1291+
1292+
// Test normal float values still work
1293+
let normal_float = Variant::Float(3.14f32);
1294+
let normal_result = variant_to_json_value(&normal_float)?;
1295+
assert!(matches!(normal_result, Value::Number(_)));
1296+
1297+
let normal_double = Variant::Double(2.71828f64);
1298+
let normal_double_result = variant_to_json_value(&normal_double)?;
1299+
assert!(matches!(normal_double_result, Value::Number(_)));
1300+
1301+
Ok(())
1302+
}
12491303
}

0 commit comments

Comments
 (0)