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 f32 {
93 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
94 statement
95 .bind_double(start_index, *self as f64)
96 .with_context(|| format!("Failed to bind f64 at index {start_index}"))?;
97 Ok(start_index + 1)
98 }
99}
100
101impl Column for f32 {
102 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
103 let result = statement
104 .column_double(start_index)
105 .with_context(|| format!("Failed to parse f32 at index {start_index}"))?
106 as f32;
107
108 Ok((result, start_index + 1))
109 }
110}
111
112impl Bind for i32 {
113 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
114 statement
115 .bind_int(start_index, *self)
116 .with_context(|| format!("Failed to bind i32 at index {start_index}"))?;
117
118 Ok(start_index + 1)
119 }
120}
121
122impl Column for i32 {
123 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
124 let result = statement.column_int(start_index)?;
125 Ok((result, start_index + 1))
126 }
127}
128
129impl Bind for i64 {
130 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
131 statement
132 .bind_int64(start_index, *self)
133 .with_context(|| format!("Failed to bind i64 at index {start_index}"))?;
134 Ok(start_index + 1)
135 }
136}
137
138impl Column for i64 {
139 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
140 let result = statement.column_int64(start_index)?;
141 Ok((result, start_index + 1))
142 }
143}
144
145impl Bind for u32 {
146 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
147 (*self as i64)
148 .bind(statement, start_index)
149 .with_context(|| format!("Failed to bind usize at index {start_index}"))
150 }
151}
152
153impl Column for u32 {
154 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
155 let result = statement.column_int64(start_index)?;
156 Ok((result as u32, start_index + 1))
157 }
158}
159
160impl Bind for usize {
161 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
162 (*self as i64)
163 .bind(statement, start_index)
164 .with_context(|| format!("Failed to bind usize at index {start_index}"))
165 }
166}
167
168impl Column for usize {
169 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
170 let result = statement.column_int64(start_index)?;
171 Ok((result as usize, start_index + 1))
172 }
173}
174
175impl Bind for &str {
176 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
177 statement.bind_text(start_index, self)?;
178 Ok(start_index + 1)
179 }
180}
181
182impl Bind for Arc<str> {
183 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
184 statement.bind_text(start_index, self.as_ref())?;
185 Ok(start_index + 1)
186 }
187}
188
189impl Bind for String {
190 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
191 statement.bind_text(start_index, self)?;
192 Ok(start_index + 1)
193 }
194}
195
196impl Column for Arc<str> {
197 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
198 let result = statement.column_text(start_index)?;
199 Ok((Arc::from(result), start_index + 1))
200 }
201}
202
203impl Column for String {
204 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
205 let result = statement.column_text(start_index)?;
206 Ok((result.to_owned(), start_index + 1))
207 }
208}
209
210impl<T: Bind> Bind for Option<T> {
211 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
212 if let Some(this) = self {
213 this.bind(statement, start_index)
214 } else {
215 statement.bind_null(start_index)?;
216 Ok(start_index + 1)
217 }
218 }
219}
220
221impl<T: Column> Column for Option<T> {
222 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
223 if let SqlType::Null = statement.column_type(start_index)? {
224 Ok((None, start_index + 1))
225 } else {
226 T::column(statement, start_index).map(|(result, next_index)| (Some(result), next_index))
227 }
228 }
229}
230
231impl<T: Bind, const COUNT: usize> Bind for [T; COUNT] {
232 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
233 let mut current_index = start_index;
234 for binding in self {
235 current_index = binding.bind(statement, current_index)?
236 }
237
238 Ok(current_index)
239 }
240}
241
242impl<T: Column + Default + Copy, const COUNT: usize> Column for [T; COUNT] {
243 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
244 let mut array = [Default::default(); COUNT];
245 let mut current_index = start_index;
246 for i in 0..COUNT {
247 (array[i], current_index) = T::column(statement, current_index)?;
248 }
249 Ok((array, current_index))
250 }
251}
252
253impl<T: Bind> Bind for Vec<T> {
254 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
255 let mut current_index = start_index;
256 for binding in self.iter() {
257 current_index = binding.bind(statement, current_index)?
258 }
259
260 Ok(current_index)
261 }
262}
263
264impl<T: Bind> Bind for &[T] {
265 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
266 let mut current_index = start_index;
267 for binding in *self {
268 current_index = binding.bind(statement, current_index)?
269 }
270
271 Ok(current_index)
272 }
273}
274
275impl Bind for &Path {
276 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
277 self.as_os_str().as_bytes().bind(statement, start_index)
278 }
279}
280
281impl Bind for Arc<Path> {
282 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
283 self.as_ref().bind(statement, start_index)
284 }
285}
286
287impl Bind for PathBuf {
288 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
289 (self.as_ref() as &Path).bind(statement, start_index)
290 }
291}
292
293impl Column for PathBuf {
294 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
295 let blob = statement.column_blob(start_index)?;
296
297 Ok((
298 PathBuf::from(OsStr::from_bytes(blob).to_owned()),
299 start_index + 1,
300 ))
301 }
302}
303
304/// Unit impls do nothing. This simplifies query macros
305impl Bind for () {
306 fn bind(&self, _statement: &Statement, start_index: i32) -> Result<i32> {
307 Ok(start_index)
308 }
309}
310
311impl Column for () {
312 fn column(_statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
313 Ok(((), start_index))
314 }
315}
316
317impl<T1: Bind, T2: Bind> Bind for (T1, T2) {
318 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
319 let next_index = self.0.bind(statement, start_index)?;
320 self.1.bind(statement, next_index)
321 }
322}
323
324impl<T1: Column, T2: Column> Column for (T1, T2) {
325 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
326 let (first, next_index) = T1::column(statement, start_index)?;
327 let (second, next_index) = T2::column(statement, next_index)?;
328 Ok(((first, second), next_index))
329 }
330}
331
332impl<T1: Bind, T2: Bind, T3: Bind> Bind for (T1, T2, T3) {
333 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
334 let next_index = self.0.bind(statement, start_index)?;
335 let next_index = self.1.bind(statement, next_index)?;
336 self.2.bind(statement, next_index)
337 }
338}
339
340impl<T1: Column, T2: Column, T3: Column> Column for (T1, T2, T3) {
341 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
342 let (first, next_index) = T1::column(statement, start_index)?;
343 let (second, next_index) = T2::column(statement, next_index)?;
344 let (third, next_index) = T3::column(statement, next_index)?;
345 Ok(((first, second, third), next_index))
346 }
347}
348
349impl<T1: Bind, T2: Bind, T3: Bind, T4: Bind> Bind for (T1, T2, T3, T4) {
350 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
351 let next_index = self.0.bind(statement, start_index)?;
352 let next_index = self.1.bind(statement, next_index)?;
353 let next_index = self.2.bind(statement, next_index)?;
354 self.3.bind(statement, next_index)
355 }
356}
357
358impl<T1: Column, T2: Column, T3: Column, T4: Column> Column for (T1, T2, T3, T4) {
359 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
360 let (first, next_index) = T1::column(statement, start_index)?;
361 let (second, next_index) = T2::column(statement, next_index)?;
362 let (third, next_index) = T3::column(statement, next_index)?;
363 let (fourth, next_index) = T4::column(statement, next_index)?;
364 Ok(((first, second, third, fourth), next_index))
365 }
366}
367
368impl<T1: Bind, T2: Bind, T3: Bind, T4: Bind, T5: Bind> Bind for (T1, T2, T3, T4, T5) {
369 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
370 let next_index = self.0.bind(statement, start_index)?;
371 let next_index = self.1.bind(statement, next_index)?;
372 let next_index = self.2.bind(statement, next_index)?;
373 let next_index = self.3.bind(statement, next_index)?;
374 self.4.bind(statement, next_index)
375 }
376}
377
378impl<T1: Column, T2: Column, T3: Column, T4: Column, T5: Column> Column for (T1, T2, T3, T4, T5) {
379 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
380 let (first, next_index) = T1::column(statement, start_index)?;
381 let (second, next_index) = T2::column(statement, next_index)?;
382 let (third, next_index) = T3::column(statement, next_index)?;
383 let (fourth, next_index) = T4::column(statement, next_index)?;
384 let (fifth, next_index) = T5::column(statement, next_index)?;
385 Ok(((first, second, third, fourth, fifth), next_index))
386 }
387}