1use std::{
2 ffi::OsStr,
3 os::unix::prelude::OsStrExt,
4 path::{Path, PathBuf},
5 sync::Arc,
6};
7
8use anyhow::{Context, Result};
9
10use crate::statement::{SqlType, Statement};
11
12pub trait Bind {
13 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32>;
14}
15
16pub trait Column: Sized {
17 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)>;
18}
19
20impl Bind for bool {
21 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
22 statement
23 .bind(self.then_some(1).unwrap_or(0), start_index)
24 .with_context(|| format!("Failed to bind bool at index {start_index}"))
25 }
26}
27
28impl Column for bool {
29 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
30 i32::column(statement, start_index)
31 .map(|(i, next_index)| (i != 0, next_index))
32 .with_context(|| format!("Failed to read bool at index {start_index}"))
33 }
34}
35
36impl Bind for &[u8] {
37 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
38 statement
39 .bind_blob(start_index, self)
40 .with_context(|| format!("Failed to bind &[u8] at index {start_index}"))?;
41 Ok(start_index + 1)
42 }
43}
44
45impl<const C: usize> Bind for &[u8; C] {
46 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
47 statement
48 .bind_blob(start_index, self.as_slice())
49 .with_context(|| format!("Failed to bind &[u8; C] at index {start_index}"))?;
50 Ok(start_index + 1)
51 }
52}
53
54impl Bind for Vec<u8> {
55 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
56 statement
57 .bind_blob(start_index, self)
58 .with_context(|| format!("Failed to bind Vec<u8> at index {start_index}"))?;
59 Ok(start_index + 1)
60 }
61}
62
63impl Column for Vec<u8> {
64 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
65 let result = statement
66 .column_blob(start_index)
67 .with_context(|| format!("Failed to read Vec<u8> at index {start_index}"))?;
68
69 Ok((Vec::from(result), start_index + 1))
70 }
71}
72
73impl Bind for f64 {
74 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
75 statement
76 .bind_double(start_index, *self)
77 .with_context(|| format!("Failed to bind f64 at index {start_index}"))?;
78 Ok(start_index + 1)
79 }
80}
81
82impl Column for f64 {
83 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
84 let result = statement
85 .column_double(start_index)
86 .with_context(|| format!("Failed to parse f64 at index {start_index}"))?;
87
88 Ok((result, start_index + 1))
89 }
90}
91
92impl Bind for i32 {
93 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
94 statement
95 .bind_int(start_index, *self)
96 .with_context(|| format!("Failed to bind i32 at index {start_index}"))?;
97
98 Ok(start_index + 1)
99 }
100}
101
102impl Column for i32 {
103 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
104 let result = statement.column_int(start_index)?;
105 Ok((result, start_index + 1))
106 }
107}
108
109impl Bind for i64 {
110 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
111 statement
112 .bind_int64(start_index, *self)
113 .with_context(|| format!("Failed to bind i64 at index {start_index}"))?;
114 Ok(start_index + 1)
115 }
116}
117
118impl Column for i64 {
119 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
120 let result = statement.column_int64(start_index)?;
121 Ok((result, start_index + 1))
122 }
123}
124
125impl Bind for usize {
126 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
127 (*self as i64)
128 .bind(statement, start_index)
129 .with_context(|| format!("Failed to bind usize at index {start_index}"))
130 }
131}
132
133impl Column for usize {
134 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
135 let result = statement.column_int64(start_index)?;
136 Ok((result as usize, start_index + 1))
137 }
138}
139
140impl Bind for &str {
141 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
142 statement.bind_text(start_index, self)?;
143 Ok(start_index + 1)
144 }
145}
146
147impl Bind for Arc<str> {
148 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
149 statement.bind_text(start_index, self.as_ref())?;
150 Ok(start_index + 1)
151 }
152}
153
154impl Bind for String {
155 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
156 statement.bind_text(start_index, self)?;
157 Ok(start_index + 1)
158 }
159}
160
161impl Column for Arc<str> {
162 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
163 let result = statement.column_text(start_index)?;
164 Ok((Arc::from(result), start_index + 1))
165 }
166}
167
168impl Column for String {
169 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
170 let result = statement.column_text(start_index)?;
171 Ok((result.to_owned(), start_index + 1))
172 }
173}
174
175impl<T: Bind> Bind for Option<T> {
176 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
177 if let Some(this) = self {
178 this.bind(statement, start_index)
179 } else {
180 statement.bind_null(start_index)?;
181 Ok(start_index + 1)
182 }
183 }
184}
185
186impl<T: Column> Column for Option<T> {
187 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
188 if let SqlType::Null = statement.column_type(start_index)? {
189 Ok((None, start_index + 1))
190 } else {
191 T::column(statement, start_index).map(|(result, next_index)| (Some(result), next_index))
192 }
193 }
194}
195
196impl<T: Bind, const COUNT: usize> Bind for [T; COUNT] {
197 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
198 let mut current_index = start_index;
199 for binding in self {
200 current_index = binding.bind(statement, current_index)?
201 }
202
203 Ok(current_index)
204 }
205}
206
207impl<T: Column + Default + Copy, const COUNT: usize> Column for [T; COUNT] {
208 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
209 let mut array = [Default::default(); COUNT];
210 let mut current_index = start_index;
211 for i in 0..COUNT {
212 (array[i], current_index) = T::column(statement, current_index)?;
213 }
214 Ok((array, current_index))
215 }
216}
217
218impl<T: Bind> Bind for Vec<T> {
219 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
220 let mut current_index = start_index;
221 for binding in self.iter() {
222 current_index = binding.bind(statement, current_index)?
223 }
224
225 Ok(current_index)
226 }
227}
228
229impl<T: Bind> Bind for &[T] {
230 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
231 let mut current_index = start_index;
232 for binding in *self {
233 current_index = binding.bind(statement, current_index)?
234 }
235
236 Ok(current_index)
237 }
238}
239
240impl Bind for &Path {
241 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
242 self.as_os_str().as_bytes().bind(statement, start_index)
243 }
244}
245
246impl Bind for Arc<Path> {
247 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
248 self.as_ref().bind(statement, start_index)
249 }
250}
251
252impl Bind for PathBuf {
253 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
254 (self.as_ref() as &Path).bind(statement, start_index)
255 }
256}
257
258impl Column for PathBuf {
259 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
260 let blob = statement.column_blob(start_index)?;
261
262 Ok((
263 PathBuf::from(OsStr::from_bytes(blob).to_owned()),
264 start_index + 1,
265 ))
266 }
267}
268
269/// Unit impls do nothing. This simplifies query macros
270impl Bind for () {
271 fn bind(&self, _statement: &Statement, start_index: i32) -> Result<i32> {
272 Ok(start_index)
273 }
274}
275
276impl Column for () {
277 fn column(_statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
278 Ok(((), start_index))
279 }
280}
281
282impl<T1: Bind, T2: Bind> Bind for (T1, T2) {
283 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
284 let next_index = self.0.bind(statement, start_index)?;
285 self.1.bind(statement, next_index)
286 }
287}
288
289impl<T1: Column, T2: Column> Column for (T1, T2) {
290 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
291 let (first, next_index) = T1::column(statement, start_index)?;
292 let (second, next_index) = T2::column(statement, next_index)?;
293 Ok(((first, second), next_index))
294 }
295}
296
297impl<T1: Bind, T2: Bind, T3: Bind> Bind for (T1, T2, T3) {
298 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
299 let next_index = self.0.bind(statement, start_index)?;
300 let next_index = self.1.bind(statement, next_index)?;
301 self.2.bind(statement, next_index)
302 }
303}
304
305impl<T1: Column, T2: Column, T3: Column> Column for (T1, T2, T3) {
306 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
307 let (first, next_index) = T1::column(statement, start_index)?;
308 let (second, next_index) = T2::column(statement, next_index)?;
309 let (third, next_index) = T3::column(statement, next_index)?;
310 Ok(((first, second, third), next_index))
311 }
312}
313
314impl<T1: Bind, T2: Bind, T3: Bind, T4: Bind> Bind for (T1, T2, T3, T4) {
315 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
316 let next_index = self.0.bind(statement, start_index)?;
317 let next_index = self.1.bind(statement, next_index)?;
318 let next_index = self.2.bind(statement, next_index)?;
319 self.3.bind(statement, next_index)
320 }
321}
322
323impl<T1: Column, T2: Column, T3: Column, T4: Column> Column for (T1, T2, T3, T4) {
324 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
325 let (first, next_index) = T1::column(statement, start_index)?;
326 let (second, next_index) = T2::column(statement, next_index)?;
327 let (third, next_index) = T3::column(statement, next_index)?;
328 let (fourth, next_index) = T4::column(statement, next_index)?;
329 Ok(((first, second, third, fourth), next_index))
330 }
331}
332
333impl<T1: Bind, T2: Bind, T3: Bind, T4: Bind, T5: Bind> Bind for (T1, T2, T3, T4, T5) {
334 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
335 let next_index = self.0.bind(statement, start_index)?;
336 let next_index = self.1.bind(statement, next_index)?;
337 let next_index = self.2.bind(statement, next_index)?;
338 let next_index = self.3.bind(statement, next_index)?;
339 self.4.bind(statement, next_index)
340 }
341}
342
343impl<T1: Column, T2: Column, T3: Column, T4: Column, T5: Column> Column for (T1, T2, T3, T4, T5) {
344 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
345 let (first, next_index) = T1::column(statement, start_index)?;
346 let (second, next_index) = T2::column(statement, next_index)?;
347 let (third, next_index) = T3::column(statement, next_index)?;
348 let (fourth, next_index) = T4::column(statement, next_index)?;
349 let (fifth, next_index) = T5::column(statement, next_index)?;
350 Ok(((first, second, third, fourth, fifth), next_index))
351 }
352}