Path: blob/main/crates/polars-core/src/frame/validation.rs
8424 views
use polars_error::{PolarsResult, polars_bail};1use polars_utils::aliases::{InitHashMaps, PlHashSet};23use crate::frame::column::Column;45/// Checks for duplicates and mismatching heights.6pub(super) fn validate_columns_slice(7expected_height: usize,8columns: &[Column],9) -> PolarsResult<()> {10if columns.is_empty() {11return Ok(());12}1314let expected_height_msg = || {15if let Some(c) = columns.iter().find(|c| c.len() == expected_height) {16format!("height of column '{}' ({})", c.name(), c.len())17} else {18format!("DataFrame height ({expected_height})")19}20};2122if columns.len() <= 4 {23// Too small to be worth spawning a hashmap for, this is at most 6 comparisons.24for (i, col) in columns.iter().enumerate() {25if col.len() != expected_height {26polars_bail!(27ShapeMismatch:28"height of column '{}' ({}) does not match {}",29col.name(), col.len(), expected_height_msg()30)31}3233let name = col.name();3435for other in columns.iter().skip(i + 1) {36if other.name() == name {37polars_bail!(duplicate = name);38}39}40}41} else {42let mut names = PlHashSet::with_capacity(columns.len());4344for col in columns {45let col_name = col.name();46let col_len = col.len();4748if col_len != expected_height {49polars_bail!(50ShapeMismatch:51"height of column '{}' ({}) does not match {}",52col_name, col_len, expected_height_msg()53)54}5556if names.contains(col_name) {57polars_bail!(duplicate = col_name)58}5960names.insert(col_name);61}62}6364Ok(())65}6667pub(super) fn ensure_names_unique<T>(names: &[T]) -> PolarsResult<()>68where69T: AsRef<str>,70{71// Always unique.72if names.len() <= 1 {73return Ok(());74}7576if names.len() <= 4 {77// Too small to be worth spawning a hashmap for, this is at most 6 comparisons.78for i in 0..names.len() - 1 {79let name = names[i].as_ref();8081for other in names.iter().skip(i + 1) {82if name == other.as_ref() {83polars_bail!(duplicate = name);84}85}86}87} else {88let mut names_set: PlHashSet<&str> = PlHashSet::with_capacity(names.len());8990for name in names {91let name = name.as_ref();9293if !names_set.insert(name) {94polars_bail!(duplicate = name);95}96}97}98Ok(())99}100101102