bindable.rs

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