stringqb/src/types.rs

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()
}
}