use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Column {
pub name: String,
pub data_type: String,
pub attributes: Vec<String>,
pub modifiers: Vec<ColumnModifier>,
pub is_foreign: bool,
pub foreign_target: Option<String>,
pub is_relationship: bool,
pub relationship_type: Option<String>,
pub relationship_model: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ColumnModifier {
pub name: String,
pub value: Option<String>,
}
impl Column {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
data_type: "string".to_string(),
attributes: vec![],
modifiers: vec![],
is_foreign: false,
foreign_target: None,
is_relationship: false,
relationship_type: None,
relationship_model: None,
}
}
pub fn is_timestamps(&self) -> bool {
matches!(self.name.as_str(), "created_at" | "updated_at")
}
pub fn is_soft_deletes(&self) -> bool {
self.name == "deleted_at"
}
pub fn php_type(&self) -> &str {
match self.data_type.as_str() {
"string" | "char" | "text" | "longtext" | "mediumtext" | "enum" | "set"
| "ipAddress" | "macAddress" | "uuid" | "ulid" => "string",
"integer" | "bigInteger" | "mediumInteger" | "smallInteger" | "tinyInteger"
| "unsignedInteger" | "unsignedBigInteger" | "unsignedMediumInteger"
| "unsignedSmallInteger" | "unsignedTinyInteger" => "int",
"boolean" => "bool",
"float" | "double" | "decimal" => "float",
"date" | "datetime" | "timestamp" | "timestamps" | "datetimeTz" | "timestampTz" => "\\Carbon\\Carbon",
"json" | "jsonb" | "array" => "array",
_ => "mixed",
}
}
pub fn cast_type(&self) -> Option<&str> {
match self.data_type.as_str() {
"boolean" => Some("bool"),
"integer" | "bigInteger" => Some("integer"),
"float" | "double" => Some("float"),
"decimal" => Some("decimal"),
"json" | "jsonb" | "array" => Some("array"),
"datetime" | "timestamp" | "datetimeTz" | "timestampTz" => Some("datetime"),
"date" => Some("date"),
_ => None,
}
}
pub fn migration_type(&self) -> &str {
self.data_type.as_str()
}
pub fn is_unsigned_numeric(&self) -> bool {
matches!(
self.data_type.as_str(),
"unsignedInteger" | "unsignedBigInteger" | "unsignedMediumInteger"
| "unsignedSmallInteger" | "unsignedTinyInteger"
)
}
pub fn has_modifier(&self, name: &str) -> bool {
self.modifiers.iter().any(|m| m.name == name)
}
pub fn get_modifier(&self, name: &str) -> Option<&ColumnModifier> {
self.modifiers.iter().find(|m| m.name == name)
}
}