Skip to main content

laminar_core/time/cast/
mod.rs

1//! Cast any `Timestamp(_)` array to `TimestampMillisecondArray`.
2
3use std::fmt;
4
5use arrow::array::{Array, TimestampMillisecondArray};
6use arrow::datatypes::{DataType, TimeUnit};
7
8/// Error returned when a column isn't a `Timestamp(_)` type or Arrow's
9/// cast kernel fails.
10#[derive(Debug)]
11pub struct CastError(pub String);
12
13impl fmt::Display for CastError {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        write!(f, "{}", self.0)
16    }
17}
18
19impl std::error::Error for CastError {}
20
21/// Cast any `Timestamp(_)` array to `TimestampMillisecondArray`.
22///
23/// # Errors
24///
25/// [`CastError`] if `array` isn't a `Timestamp(_)` or the cast fails.
26pub fn cast_to_millis_array(array: &dyn Array) -> Result<TimestampMillisecondArray, CastError> {
27    if !matches!(array.data_type(), DataType::Timestamp(_, _)) {
28        return Err(CastError(format!(
29            "event-time column must be Timestamp(_), found {:?}",
30            array.data_type()
31        )));
32    }
33    let cast = arrow::compute::cast(array, &DataType::Timestamp(TimeUnit::Millisecond, None))
34        .map_err(|e| CastError(e.to_string()))?;
35    cast.as_any()
36        .downcast_ref::<TimestampMillisecondArray>()
37        .cloned()
38        .ok_or_else(|| CastError("arrow cast did not yield TimestampMillisecond".into()))
39}
40
41#[cfg(test)]
42mod tests;