use core::ffi::c_int;
use crate::utils::repeat;
use crate::{BindValue, Error, Statement};
pub const BIND_INDEX: c_int = 1;
pub trait Bind {
fn bind(&self, stmt: &mut Statement) -> Result<(), Error>;
}
impl<T> Bind for &T
where
T: ?Sized + Bind,
{
#[inline]
fn bind(&self, stmt: &mut Statement) -> Result<(), Error> {
(*self).bind(stmt)
}
}
impl Bind for () {
#[inline]
fn bind(&self, _stmt: &mut Statement) -> Result<(), Error> {
Ok(())
}
}
macro_rules! ty {
($_:ident) => {
"i64"
};
}
macro_rules! implement_tuple {
($ty0:ident $var0:ident $v0:literal $v1:literal $(, $ty:ident $var:ident $v0n:literal $v1n:literal)* $(,)? ) => {
#[doc = concat!("c.execute(\"CREATE TABLE users (", stringify!($var0), " INTEGER" $(, ", ", stringify!($var), " INTEGER")*, ")\")?;")]
#[doc = concat!("c.execute(\"INSERT INTO users VALUES (", stringify!($v0) $(, ", ", stringify!($v0n))*, ")\")?;")]
#[doc = concat!("let mut stmt = c.prepare(\"SELECT * FROM users WHERE ", stringify!($var0), " = ?" $(, " AND ", stringify!($var), " = ?")*, "\")?;")]
#[doc = concat!("stmt.bind((", stringify!($v0), "," $(, " ", stringify!($v0n), ",")*, "))?;")]
#[doc = concat!("let v = stmt.next::<(", ty!($ty0), ",", $(" ", ty!($ty), ",",)* ")>()?.expect(\"missing\");")]
$(#[doc = concat!("assert_eq!(v.", stringify!($v0n), ", ", stringify!($v0n), ");")])*
#[doc = concat!("assert!(stmt.step()?.is_done());")]
impl<$ty0, $($ty,)*> Bind for ($ty0, $($ty,)*)
where
$ty0: BindValue,
$($ty: BindValue,)*
{
#[inline]
fn bind(&self, stmt: &mut Statement) -> Result<(), Error> {
let ($var0, $($var,)*) = self;
BindValue::bind_value($var0, stmt, $v1)?;
$(BindValue::bind_value($var, stmt, $v1n)?;)*
Ok(())
}
}
};
}
repeat!(implement_tuple);