//! 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` | BYTEA | //! //! ## SQLite Type Mappings //! //! | Rust type(s) | SQLite type(s) | //! |-------------------------------|-----------------------------------------------| //! | `i8`/`i16`/`i32`/`i64` | INTEGER | //! | `f64` | REAL | //! | `&str`/`String` | TEXT | //! | `&[u8]`/`Vec` | 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` | 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), } /// 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>, { 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); /// Types that can be converted to a type that the driver understands pub trait ToDriver { fn to_driver(&self) -> Result, ()>; } /// 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 { value: Option, } fn is_str(s: &(dyn Any)) -> bool { s.is::<&str>() } fn is_string(s: &(dyn Any)) -> bool { s.is::() } fn is_bool(v: &(dyn Any)) -> bool { v.is::() } impl SQLType { pub fn is_some(&self) -> bool { match self.value { None => false, _ => true, } } pub fn is_none(&self) -> bool { !self.is_some() } }