rust-db-blueprint 0.1.0

A Rust code generator — reads YAML draft files and generates Axum + SQLx models, migrations, handlers, routes, requests, tests, and seeds
Documentation
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)
    }
}