use polars::{
prelude::{NamedFrom, PlSmallStr, is_in},
series::{IntoSeries, Series},
};
use crate::{core::Domain, error::Fallible};
#[cfg(feature = "ffi")]
mod ffi;
#[cfg(test)]
mod test;
#[derive(Debug, Clone, PartialEq, Default)]
pub struct EnumDomain {
categories: Series,
}
impl EnumDomain {
pub fn new(categories: Series) -> Fallible<Self> {
if !categories.dtype().is_string() {
return fallible!(
MakeDomain,
"categories dtype ({}) must be string",
categories.dtype()
);
}
let n_duplicates = categories.len() - categories.n_unique()?;
if n_duplicates != 0 {
return fallible!(
MakeDomain,
"categories must be distinct. Found {:?} duplicates.",
n_duplicates
);
}
Ok(EnumDomain { categories })
}
pub fn categories(&self) -> &Series {
&self.categories
}
}
impl Domain for EnumDomain {
type Carrier = PlSmallStr;
fn member(&self, value: &Self::Carrier) -> Fallible<bool> {
Ok(is_in(
&self.categories,
&Series::new("".into(), &vec![value.as_str()])
.implode()?
.into_series(),
false,
)?
.get(0)
.unwrap())
}
}