Skip to main content

floe_core/checks/
not_null.rs

1use polars::prelude::DataFrame;
2
3use super::RowError;
4use crate::{ConfigError, FloeResult};
5
6pub fn not_null_errors(df: &DataFrame, required_cols: &[String]) -> FloeResult<Vec<Vec<RowError>>> {
7    let mut errors_per_row = vec![Vec::new(); df.height()];
8    if required_cols.is_empty() {
9        return Ok(errors_per_row);
10    }
11
12    let mut null_masks = Vec::with_capacity(required_cols.len());
13    for name in required_cols {
14        let mask = df
15            .column(name)
16            .map_err(|err| {
17                Box::new(ConfigError(format!(
18                    "required column {name} not found: {err}"
19                )))
20            })?
21            .is_null();
22        null_masks.push(mask);
23    }
24
25    for (row_idx, errors) in errors_per_row.iter_mut().enumerate() {
26        for (col, mask) in required_cols.iter().zip(null_masks.iter()) {
27            if mask.get(row_idx).unwrap_or(false) {
28                errors.push(RowError::new("not_null", col, "required value missing"));
29            }
30        }
31    }
32
33    Ok(errors_per_row)
34}