bindable.rs

  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}