wires

summary refs log tree commit diff
path: root/wyrd_sqlite/src/params.rs
diff options
context:
space:
mode:
authorwires <wires@noreply.wires.systems>2025-10-24 11:29:46 -0400
committerwires <wires@noreply.wires.systems>2025-10-24 11:29:46 -0400
commit92e4cfc123a1d26265128634850a2b73bac761c2 (patch)
treebdbab6c9ac4a8e981888700e16a7e79b1afb3b27 /wyrd_sqlite/src/params.rs
parentinitial commit (diff)
downloadwyrd-main.tar.gz
first draft of sqlite wrapper HEAD main
Diffstat (limited to 'wyrd_sqlite/src/params.rs')
-rw-r--r--wyrd_sqlite/src/params.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/wyrd_sqlite/src/params.rs b/wyrd_sqlite/src/params.rs
new file mode 100644
index 0000000..4561c40
--- /dev/null
+++ b/wyrd_sqlite/src/params.rs
@@ -0,0 +1,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);