Skip to main content

into_vec

Function into_vec 

Source
pub fn into_vec<T>(data: &DoraArray) -> Result<Vec<T>, Report>
where T: Copy + NumCast + 'static,
Expand description

Tries to convert the given payload into a Vec of integers or floats.

The array’s element type is cast to T per element via num::NumCast, so the source and target types need not match (e.g. a UInt64Array into a Vec<f64>).

§Precision

The per-element cast goes through num::NumCast/num::ToPrimitive, so it is lossy exactly where an as cast is: a float source with a fractional part is truncated toward zero into an integer target — it is not rounded, and it does not error. Likewise an integer is rounded to the nearest representable float without error, which is only exact while it fits the float’s mantissa: up to 2^53 in magnitude for f64, 2^24 for f32 (so e.g. u64/i64 → f64 can lose low bits). Narrowing f64 → f32 likewise rounds, and a magnitude beyond f32’s range becomes ±infinity rather than an error. Converting between integer types that both hold the value is exact.

§Errors

Returns an error if the array contains any null values (consistent with every other TryFrom<&DoraArray> impl in this crate), if the array’s data type is not a supported integer or float type, or if any element is out of range for an integer T (e.g. a negative float into an unsigned target, NaN, or a magnitude the target cannot hold). A merely fractional float is in range and is truncated, and a float target never errors on range, per Precision above.

use dora_arrow_convert::{IntoArrow, into_vec};

// Values are cast element-wise to the requested target type.
let data = vec![1u64, 2, 3].into_arrow();
assert_eq!(into_vec::<u64>(&data).ok(), Some(vec![1, 2, 3]));
assert_eq!(into_vec::<f64>(&data).ok(), Some(vec![1.0, 2.0, 3.0]));

// Float -> integer truncates toward zero (it does not round or error).
let floats = vec![1.9f64, -2.9].into_arrow();
assert_eq!(into_vec::<i64>(&floats).ok(), Some(vec![1, -2]));

// Integer -> float rounds once the value exceeds the mantissa:
// 2^53 + 1 has no exact `f64` representation.
let big = vec![(1u64 << 53) + 1].into_arrow();
assert_eq!(into_vec::<f64>(&big).ok(), Some(vec![(1u64 << 53) as f64]));

// f64 -> f32 overflows to infinity instead of erroring.
let huge = vec![1e300f64].into_arrow();
assert_eq!(into_vec::<f32>(&huge).ok(), Some(vec![f32::INFINITY]));

// NaN is out of range for an integer target, so it errors.
let nan = vec![f64::NAN].into_arrow();
assert!(into_vec::<i64>(&nan).is_err());

// Unsupported (non-numeric) array types are rejected.
let strings = vec!["a".to_string(), "b".to_string()].into_arrow();
assert!(into_vec::<u64>(&strings).is_err());