Skip to main content

rust_ef_postgres/
type_mapping.rs

1//! Rust type to PostgreSQL type mapping.
2
3pub struct PostgresTypeMapping;
4
5impl PostgresTypeMapping {
6    pub fn map_type(rust_type: &str) -> &'static str {
7        match rust_type {
8            "i16" => "SMALLINT",
9            "i32" => "INTEGER",
10            "i64" => "BIGINT",
11            "u16" => "SMALLINT",
12            "u32" => "INTEGER",
13            "u64" => "BIGINT",
14            "f32" => "REAL",
15            "f64" => "DOUBLE PRECISION",
16            "bool" => "BOOLEAN",
17            "String" => "TEXT",
18            "Vec<u8>" => "BYTEA",
19            // Native chrono/uuid/decimal type mappings — used by
20            // `PostgresTypeMapping::column_definition` when the entity meta
21            // carries the simple type name. Note: `std::any::type_name`
22            // produces fully-qualified names (e.g. "chrono::DateTime<chrono::Utc>")
23            // which are handled by `MigrationDialect::map_column_type` in the
24            // core crate's migration module.
25            "DateTime" | "DateTime<Utc>" => "TIMESTAMPTZ",
26            "NaiveDateTime" => "TIMESTAMP",
27            "NaiveDate" => "DATE",
28            "Uuid" => "UUID",
29            "Decimal" => "NUMERIC",
30            _ => "TEXT",
31        }
32    }
33
34    pub fn map_auto_increment_type(rust_type: &str) -> &'static str {
35        match rust_type {
36            "i16" => "SMALLSERIAL",
37            "i32" => "SERIAL",
38            "i64" => "BIGSERIAL",
39            _ => "SERIAL",
40        }
41    }
42
43    pub fn column_definition(
44        _column_name: &str,
45        rust_type: &str,
46        is_required: bool,
47        is_auto_increment: bool,
48        max_length: Option<usize>,
49    ) -> String {
50        let pg_type = if is_auto_increment {
51            Self::map_auto_increment_type(rust_type).to_string()
52        } else {
53            let base_type = Self::map_type(rust_type);
54            match (base_type, max_length) {
55                ("TEXT", Some(n)) => format!("VARCHAR({})", n),
56                (t, _) => t.to_string(),
57            }
58        };
59
60        if is_required {
61            format!("{} NOT NULL", pg_type)
62        } else {
63            pg_type
64        }
65    }
66}