#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "UPPERCASE"))]
pub enum SQLiteType {
Integer,
Text,
Blob,
Real,
Numeric,
#[default]
Any,
}
impl SQLiteType {
#[must_use]
pub fn from_attribute_name(name: &str) -> Option<Self> {
if name.eq_ignore_ascii_case("integer") {
Some(Self::Integer)
} else if name.eq_ignore_ascii_case("text") {
Some(Self::Text)
} else if name.eq_ignore_ascii_case("blob") {
Some(Self::Blob)
} else if name.eq_ignore_ascii_case("real") {
Some(Self::Real)
} else if name.eq_ignore_ascii_case("number") || name.eq_ignore_ascii_case("numeric") {
Some(Self::Numeric)
} else if name.eq_ignore_ascii_case("boolean") {
Some(Self::Integer) } else if name.eq_ignore_ascii_case("any") {
Some(Self::Any)
} else {
None
}
}
#[must_use]
pub const fn to_sql_type(&self) -> &'static str {
match self {
Self::Integer => "INTEGER",
Self::Text => "TEXT",
Self::Blob => "BLOB",
Self::Real => "REAL",
Self::Numeric => "NUMERIC",
Self::Any => "ANY",
}
}
#[must_use]
pub fn is_valid_flag(&self, flag: &str) -> bool {
matches!(flag, "primary" | "primary_key" | "unique")
|| matches!(
(self, flag),
(Self::Integer, "autoincrement")
| (Self::Text | Self::Blob, "json")
| (Self::Text | Self::Integer, "enum")
)
}
}
impl core::fmt::Display for SQLiteType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.to_sql_type())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_attribute_name() {
assert_eq!(
SQLiteType::from_attribute_name("integer"),
Some(SQLiteType::Integer)
);
assert_eq!(
SQLiteType::from_attribute_name("INTEGER"),
Some(SQLiteType::Integer)
);
assert_eq!(
SQLiteType::from_attribute_name("text"),
Some(SQLiteType::Text)
);
assert_eq!(
SQLiteType::from_attribute_name("blob"),
Some(SQLiteType::Blob)
);
assert_eq!(
SQLiteType::from_attribute_name("boolean"),
Some(SQLiteType::Integer)
);
assert_eq!(SQLiteType::from_attribute_name("unknown"), None);
}
#[test]
fn test_to_sql_type() {
assert_eq!(SQLiteType::Integer.to_sql_type(), "INTEGER");
assert_eq!(SQLiteType::Text.to_sql_type(), "TEXT");
assert_eq!(SQLiteType::Blob.to_sql_type(), "BLOB");
assert_eq!(SQLiteType::Real.to_sql_type(), "REAL");
assert_eq!(SQLiteType::Numeric.to_sql_type(), "NUMERIC");
assert_eq!(SQLiteType::Any.to_sql_type(), "ANY");
}
#[test]
fn test_is_valid_flag() {
assert!(SQLiteType::Integer.is_valid_flag("autoincrement"));
assert!(!SQLiteType::Text.is_valid_flag("autoincrement"));
assert!(!SQLiteType::Blob.is_valid_flag("autoincrement"));
assert!(SQLiteType::Text.is_valid_flag("json"));
assert!(SQLiteType::Blob.is_valid_flag("json"));
assert!(!SQLiteType::Integer.is_valid_flag("json"));
assert!(SQLiteType::Text.is_valid_flag("enum"));
assert!(SQLiteType::Integer.is_valid_flag("enum"));
assert!(!SQLiteType::Blob.is_valid_flag("enum"));
assert!(SQLiteType::Integer.is_valid_flag("primary"));
assert!(SQLiteType::Text.is_valid_flag("unique"));
assert!(SQLiteType::Blob.is_valid_flag("primary_key"));
}
}