wires

summary refs log tree commit diff
path: root/wyrd_sqlite/src/params.rs
blob: 4561c40b949386b32e5b00fbbbfa4248470edb97 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::ffi::{c_double, c_int};

use variadics_please::all_tuples_enumerated;

use crate::{Result, Statement, ffi};

mod sealed {
    pub trait Sealed {}
}

use sealed::Sealed;

pub trait Param: Sealed {
    #[doc(hidden)]
    fn __bind_in(&self, stmt: &mut Statement<'_>, i: c_int) -> Result<()>;
}

pub trait Params: Sealed {
    #[doc(hidden)]
    fn __bind_in(&self, stmt: &mut Statement<'_>) -> Result<()>;
}

impl Sealed for c_int {}
impl Param for c_int {
    #[inline]
    fn __bind_in(&self, stmt: &mut Statement<'_>, i: c_int) -> Result<()> {
        stmt.bind_i32(i, *self)
    }
}

impl Sealed for ffi::sqlite3_int64 {}
impl Param for ffi::sqlite3_int64 {
    #[inline]
    fn __bind_in(&self, stmt: &mut Statement<'_>, i: c_int) -> Result<()> {
        stmt.bind_i64(i, *self)
    }
}

impl Sealed for c_double {}
impl Param for c_double {
    #[inline]
    fn __bind_in(&self, stmt: &mut Statement<'_>, i: c_int) -> Result<()> {
        stmt.bind_double(i, *self)
    }
}

impl<T: Param> Sealed for Option<T> {}
impl<T: Param> Param for Option<T> {
    fn __bind_in(&self, stmt: &mut Statement<'_>, i: c_int) -> Result<()> {
        match self.as_ref() {
            Some(v) => v.__bind_in(stmt, i),
            // explicitly binding NULL is required in case a previous call bound a value here
            None => stmt.bind_null(i),
        }
    }
}

impl Sealed for () {}
impl Param for () {
    #[inline]
    fn __bind_in(&self, stmt: &mut Statement<'_>, i: c_int) -> Result<()> {
        stmt.bind_null(i)
    }
}

impl Params for () {
    fn __bind_in(&self, _stmt: &mut Statement<'_>) -> Result<()> {
        Ok(())
    }
}

macro_rules! impl_params {
    ($(($i:tt, $T:ident)),*) => {
        impl<$($T:Param),*> Sealed for ($($T,)*) {}
        impl<$($T:Param),*> Params for ($($T,)*) {
            fn __bind_in(&self, stmt: &mut Statement<'_>) -> Result<()> {
                $(self.$i.__bind_in(stmt, $i + 1)?;)*
                Ok(())
            }
        }

        impl<$($T:Param),*> Sealed for ($(($T, c_int),)*) {}
        impl<$($T:Param),*> Params for ($(($T, c_int),)*) {
            fn __bind_in(&self, stmt: &mut Statement<'_>) -> Result<()> {
                $(self.$i.0.__bind_in(stmt, self.$i.1)?;)*
                Ok(())
            }
        }
    }
}

all_tuples_enumerated!(impl_params, 1, 12, T);