use crate::ibase;
use Param::*;
pub const MAX_TEXT_LENGTH: usize = 32767;
pub enum Param {
Text(String),
Integer(i64),
Floating(f64),
Timestamp(ibase::ISC_TIMESTAMP),
Null,
Binary(Vec<u8>),
Boolean(bool),
}
impl Param {
pub fn sql_type_and_subtype(&self) -> (u32, u32) {
match self {
Text(s) => {
if s.len() > MAX_TEXT_LENGTH {
(ibase::SQL_BLOB + 1, 1)
} else {
(ibase::SQL_TEXT + 1, 0)
}
}
Integer(_) => (ibase::SQL_INT64 + 1, 0),
Floating(_) => (ibase::SQL_DOUBLE + 1, 0),
Timestamp(_) => (ibase::SQL_TIMESTAMP + 1, 0),
Null => (ibase::SQL_TEXT + 1, 0),
Binary(_) => (ibase::SQL_BLOB + 1, 0),
Boolean(_) => (ibase::SQL_BOOLEAN + 1, 0),
}
}
pub fn is_null(&self) -> bool {
if let Self::Null = self {
true
} else {
false
}
}
}
pub trait IntoParam {
fn into_param(self) -> Param;
}
impl IntoParam for Vec<u8> {
fn into_param(self) -> Param {
Binary(self)
}
}
impl IntoParam for String {
fn into_param(self) -> Param {
Text(self)
}
}
impl IntoParam for i64 {
fn into_param(self) -> Param {
Integer(self)
}
}
impl IntoParam for bool {
fn into_param(self) -> Param {
Boolean(self)
}
}
macro_rules! impl_param_int {
( $( $t: ident ),+ ) => {
$(
impl IntoParam for $t {
fn into_param(self) -> Param {
(self as i64).into_param()
}
}
)+
};
}
impl_param_int!(i32, u32, i16, u16, i8, u8);
impl IntoParam for f64 {
fn into_param(self) -> Param {
Floating(self)
}
}
impl IntoParam for f32 {
fn into_param(self) -> Param {
(self as f64).into_param()
}
}
impl<T> IntoParam for Option<T>
where
T: IntoParam,
{
fn into_param(self) -> Param {
if let Some(v) = self {
v.into_param()
} else {
Null
}
}
}
impl<T, B> IntoParam for &B
where
B: ToOwned<Owned = T> + ?Sized,
T: core::borrow::Borrow<B> + IntoParam,
{
fn into_param(self) -> Param {
self.to_owned().into_param()
}
}
impl<T> From<T> for Param
where
T: IntoParam,
{
fn from(param: T) -> Self {
param.into_param()
}
}
pub trait IntoParams {
fn to_params(self) -> Vec<Param>;
}
impl IntoParams for Vec<Param> {
fn to_params(self) -> Vec<Param> {
self
}
}
impl IntoParams for () {
fn to_params(self) -> Vec<Param> {
vec![]
}
}
macro_rules! impl_into_params {
($([$t: ident, $v: ident]),+) => {
impl<$($t),+> IntoParams for ($($t,)+)
where
$( $t: IntoParam, )+
{
fn to_params(self) -> Vec<Param> {
let ( $($v,)+ ) = self;
vec![ $(
$v.into_param(),
)+ ]
}
}
};
}
macro_rules! impls_into_params {
([$t: ident, $v: ident]) => {
impl_into_params!([$t, $v]);
};
([$t: ident, $v: ident], $([$ts: ident, $vs: ident]),+ ) => {
impls_into_params!($([$ts, $vs]),+);
impl_into_params!([$t, $v], $([$ts, $vs]),+);
};
}
impls_into_params!(
[A, a],
[B, b],
[C, c],
[D, d],
[E, e],
[F, f],
[G, g],
[H, h],
[I, i],
[J, j],
[K, k],
[L, l],
[M, m],
[N, n],
[O, o]
);