use super::Column;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ColumnFamily {
Integer,
Float,
Decimal,
Text,
Bool,
}
impl Column {
pub fn family(&self) -> Option<ColumnFamily> {
let name = base_name(self.original_type.as_deref()?);
let family = match name.as_str() {
"i8" | "i16" | "i32" | "i64" | "i128" | "isize" | "u8" | "u16" | "u32" | "u64"
| "u128" | "usize" | "int" | "integer" | "bigint" | "smallint" | "serial"
| "bigserial" => ColumnFamily::Integer,
"f32" | "f64" | "float" | "double" | "real" | "number" => ColumnFamily::Float,
"decimal" | "numeric" => ColumnFamily::Decimal,
"string" | "str" | "text" | "varchar" | "char" => ColumnFamily::Text,
"bool" | "boolean" => ColumnFamily::Bool,
_ => return None,
};
Some(family)
}
}
fn base_name(t: &str) -> String {
let t = t.trim().trim_start_matches('&').trim();
let (head, args) = match (t.find('<'), t.rfind('>')) {
(Some(open), Some(close)) if open < close => (&t[..open], Some(&t[open + 1..close])),
_ => (t, None),
};
let name = head.rsplit("::").next().unwrap_or(head);
if let Some(inner) = args
&& name == "Option"
{
return base_name(inner);
}
let name = name.split('(').next().unwrap_or(name);
name.trim().to_ascii_lowercase()
}