rusticx-postgres 1.0.0

PostgreSQL adapter for the Rusticx multi-database ORM
Documentation
/// Helpers to convert between rusticx `Value` and `sqlx::postgres::PgRow`.
use rusticx_core::value::{Row, Value};
use sqlx::postgres::PgRow;
use sqlx::{Column, Row as SqlxRow, TypeInfo};

pub fn pg_row_to_row(pg_row: PgRow) -> Row {
    let mut map = Row::new();
    for col in pg_row.columns() {
        let name = col.name().to_owned();
        let type_info = col.type_info();
        let val = decode_column(&pg_row, col.ordinal(), type_info.name());
        map.insert(name, val);
    }
    map
}

fn decode_column(row: &PgRow, idx: usize, type_name: &str) -> Value {
    match type_name {
        "BOOL" => row.try_get::<bool, _>(idx).map(Value::Bool).unwrap_or(Value::Null),
        "INT2" => row.try_get::<i16, _>(idx).map(|v| Value::Int(v as i64)).unwrap_or(Value::Null),
        "INT4" => row.try_get::<i32, _>(idx).map(|v| Value::Int(v as i64)).unwrap_or(Value::Null),
        "INT8" => row.try_get::<i64, _>(idx).map(Value::Int).unwrap_or(Value::Null),
        "FLOAT4" => row.try_get::<f32, _>(idx).map(|v| Value::Float(v as f64)).unwrap_or(Value::Null),
        "FLOAT8" => row.try_get::<f64, _>(idx).map(Value::Float).unwrap_or(Value::Null),
        "TEXT" | "VARCHAR" | "BPCHAR" | "NAME" | "CHAR" => {
            row.try_get::<String, _>(idx).map(Value::Text).unwrap_or(Value::Null)
        }
        "UUID" => row
            .try_get::<uuid::Uuid, _>(idx)
            .map(Value::Uuid)
            .unwrap_or(Value::Null),
        "TIMESTAMPTZ" => row
            .try_get::<chrono::DateTime<chrono::Utc>, _>(idx)
            .map(Value::DateTime)
            .unwrap_or(Value::Null),
        "TIMESTAMP" => row
            .try_get::<chrono::NaiveDateTime, _>(idx)
            .map(|dt| Value::DateTime(dt.and_utc()))
            .unwrap_or(Value::Null),
        "JSON" | "JSONB" => row
            .try_get::<serde_json::Value, _>(idx)
            .map(Value::Json)
            .unwrap_or(Value::Null),
        "BYTEA" => row
            .try_get::<Vec<u8>, _>(idx)
            .map(Value::Bytes)
            .unwrap_or(Value::Null),
        _ => row
            .try_get::<String, _>(idx)
            .map(Value::Text)
            .unwrap_or(Value::Null),
    }
}