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 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}