qraft-core 0.1.2

Core type system, query model, decoding, and SQL lowering primitives for qraft.
Documentation
use core::fmt;

/// Untyped values returned by database drivers before `qraft` casts them.
#[derive(Debug, Default)]
#[non_exhaustive]
pub enum DbValue {
    #[default]
    Null,
    Bool(bool),
    Unsigned(u64),
    BigInt(i64),
    Double(f64),
    Text(String),
    Blob(Vec<u8>),
}

impl DbValue {
    /// Returns the coarse value kind used in cast errors.
    pub fn kind(&self) -> ValueKind {
        match self {
            DbValue::Null => ValueKind::Null,
            DbValue::Bool(..) => ValueKind::Bool,
            DbValue::Unsigned(..) => ValueKind::Unsigned,
            DbValue::BigInt(..) => ValueKind::BigInt,
            DbValue::Double(..) => ValueKind::Double,
            DbValue::Text(..) => ValueKind::Text,
            DbValue::Blob(..) => ValueKind::Blob,
        }
    }
}

macro_rules! from_for_value {
    ($sql:ty,$($ty:ty),+) => {
        paste::paste! {
            $(
                impl From<$ty> for DbValue {
                    fn from(value: $ty) -> Self {
                        DbValue::$sql(value.into())
                    }
                }
            )+
        }
    };
}

from_for_value!(Bool, bool);
from_for_value!(Unsigned, u8, u16, u32, u64);
from_for_value!(BigInt, i8, i16, i32, i64);
from_for_value!(Double, f32, f64);
from_for_value!(Text, String);
from_for_value!(Blob, Vec<u8>);

impl DbValue {
    /// Converts any supported Rust value into a driver-neutral database value.
    pub fn new<V>(value: V) -> Self
    where
        V: Into<Self>,
    {
        value.into()
    }
}

/// Broad categories used when reporting cast failures.
#[derive(Debug)]
pub enum ValueKind {
    Null,
    Bool,
    Unsigned,
    BigInt,
    Text,
    Blob,
    Double,
}

impl fmt::Display for ValueKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let str = match self {
            ValueKind::Null => "null",
            ValueKind::Bool => "bool",
            ValueKind::Unsigned => "unsigned integer",
            ValueKind::BigInt => "integer",
            ValueKind::Text => "text",
            ValueKind::Blob => "blob",
            ValueKind::Double => "floating point",
        };
        str.fmt(f)
    }
}