161 lines
5.4 KiB
Rust
161 lines
5.4 KiB
Rust
//! Shared Types for different Database drivers
|
|
//!
|
|
//! ## Postgres Type Mappings
|
|
//!
|
|
//! | Rust type | Postgres type(s) |
|
|
//! |-------------------------------|-----------------------------------------------|
|
|
//! | `bool` | BOOL |
|
|
//! | `i8` | "char" |
|
|
//! | `i16` | SMALLINT, SMALLSERIAL |
|
|
//! | `i32` | INT, SERIAL |
|
|
//! | `u32` | OID |
|
|
//! | `i64` | BIGINT, BIGSERIAL |
|
|
//! | `f32` | REAL |
|
|
//! | `f64` | DOUBLE PRECISION |
|
|
//! | `&str`/`String` | VARCHAR, CHAR(n), TEXT, CITEXT, NAME, UNKNOWN |
|
|
//! | `&[u8]`/`Vec<u8>` | BYTEA |
|
|
//!
|
|
//! ## SQLite Type Mappings
|
|
//!
|
|
//! | Rust type(s) | SQLite type(s) |
|
|
//! |-------------------------------|-----------------------------------------------|
|
|
//! | `i8`/`i16`/`i32`/`i64` | INTEGER |
|
|
//! | `f64` | REAL |
|
|
//! | `&str`/`String` | TEXT |
|
|
//! | `&[u8]`/`Vec<u8>` | BLOB |
|
|
//!
|
|
//! ## MySQL/MariaDB Type Mappings
|
|
//! | Rust type(s) | MySQL type(s) |
|
|
//! |-------------------------------|-----------------------------------------------|
|
|
//! | `i8` | signed TINYINT |
|
|
//! | `u8` | unsigned TINYINT |
|
|
//! | `i16` | signed SMALLINT |
|
|
//! | `u16` | unsigned SMALLINT |
|
|
//! | `i32` | signed MEDIUMINT, INT, INTEGER |
|
|
//! | `u32` | unsigned MEDIUMINT, INT, INTEGER |
|
|
//! | `i64` | signed BIGINT |
|
|
//! | `u64` | unsigned BIGINT |
|
|
//! | `&str`/`String` | VARCHAR, CHAR, TEXT |
|
|
//! | `&[u8]`/`Vec<u8>` | BINARY, VARBINARY, BLOB |
|
|
//! | `f32` | FLOAT |
|
|
//! | `f64` | DOUBLE, DOUBLE PRECISION |
|
|
//!
|
|
use std::any::Any;
|
|
use std::borrow::Cow;
|
|
use std::error::Error;
|
|
|
|
/// Empty struct to represent Null values
|
|
#[derive(Copy, Clone)]
|
|
pub struct Null;
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum Type {
|
|
Null,
|
|
Integer,
|
|
Real,
|
|
Text,
|
|
Blob,
|
|
}
|
|
|
|
/// An owned value
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum Value {
|
|
Null,
|
|
Integer(i64),
|
|
Real(f64),
|
|
Text(String),
|
|
Blob(Vec<u8>),
|
|
}
|
|
|
|
/// A borrowed value
|
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
pub enum ValueRef<'a> {
|
|
Null,
|
|
Integer(i64),
|
|
Real(f64),
|
|
Text(&'a str),
|
|
Blob(&'a [u8]),
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum ToDriverOutput<'a> {
|
|
Borrowed(ValueRef<'a>),
|
|
Owned(Value),
|
|
}
|
|
|
|
// Generically allow any type that can be converted into a ValueRef
|
|
// to be converted into a ToSqlOutput as well.
|
|
impl<'a, T: ?Sized> From<&'a T> for ToDriverOutput<'a>
|
|
where
|
|
&'a T: Into<ValueRef<'a>>,
|
|
{
|
|
fn from(t: &'a T) -> Self {
|
|
ToDriverOutput::Borrowed(t.into())
|
|
}
|
|
}
|
|
|
|
// We cannot also generically allow any type that can be converted
|
|
// into a Value to be converted into a ToDriverOutput because of
|
|
// coherence rules (https://github.com/rust-lang/rust/pull/46192),
|
|
// so we'll manually implement it for all the types we know can
|
|
// be converted into Values.
|
|
//macro_rules! from_value(
|
|
// ($t:ty) => (
|
|
// impl From<$t> for ToDriverOutput<'_> {
|
|
// fn from(t: $t) -> Self { ToDriverOutput::Owned(t.into())}
|
|
// }
|
|
// )
|
|
//);
|
|
//from_value!(String);
|
|
//from_value!(Null);
|
|
//from_value!(bool);
|
|
//from_value!(i8);
|
|
//from_value!(i16);
|
|
//from_value!(i32);
|
|
//from_value!(i64);
|
|
//from_value!(isize);
|
|
//from_value!(u8);
|
|
//from_value!(u16);
|
|
//from_value!(u32);
|
|
//from_value!(f64);
|
|
//from_value!(Vec<u8>);
|
|
|
|
/// Types that can be converted to a type that the driver understands
|
|
pub trait ToDriver {
|
|
fn to_driver(&self) -> Result<ToDriverOutput<'_>, ()>;
|
|
}
|
|
|
|
/// A trait for types that can be created from the result of a query on the driver
|
|
pub trait FromDriver: Sized {}
|
|
|
|
/// Enum struct for mapping between database and Rust types
|
|
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
|
|
struct SQLType<T> {
|
|
value: Option<T>,
|
|
}
|
|
|
|
fn is_str(s: &(dyn Any)) -> bool {
|
|
s.is::<&str>()
|
|
}
|
|
|
|
fn is_string(s: &(dyn Any)) -> bool {
|
|
s.is::<String>()
|
|
}
|
|
|
|
fn is_bool(v: &(dyn Any)) -> bool {
|
|
v.is::<bool>()
|
|
}
|
|
|
|
impl<T> SQLType<T> {
|
|
pub fn is_some(&self) -> bool {
|
|
match self.value {
|
|
None => false,
|
|
_ => true,
|
|
}
|
|
}
|
|
|
|
pub fn is_none(&self) -> bool {
|
|
!self.is_some()
|
|
}
|
|
}
|