bindable.rs

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