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 () {
141 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
142 statement.bind_null(start_index)?;
143 Ok(start_index + 1)
144 }
145}
146
147impl Bind for &str {
148 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
149 statement.bind_text(start_index, self)?;
150 Ok(start_index + 1)
151 }
152}
153
154impl Bind for Arc<str> {
155 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
156 statement.bind_text(start_index, self.as_ref())?;
157 Ok(start_index + 1)
158 }
159}
160
161impl Bind for String {
162 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
163 statement.bind_text(start_index, self)?;
164 Ok(start_index + 1)
165 }
166}
167
168impl Column for Arc<str> {
169 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
170 let result = statement.column_text(start_index)?;
171 Ok((Arc::from(result), start_index + 1))
172 }
173}
174
175impl Column for String {
176 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
177 let result = statement.column_text(start_index)?;
178 Ok((result.to_owned(), start_index + 1))
179 }
180}
181
182impl<T1: Bind, T2: Bind> Bind for (T1, T2) {
183 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
184 let next_index = self.0.bind(statement, start_index)?;
185 self.1.bind(statement, next_index)
186 }
187}
188
189impl<T1: Column, T2: Column> Column for (T1, T2) {
190 fn column<'a>(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
191 let (first, next_index) = T1::column(statement, start_index)?;
192 let (second, next_index) = T2::column(statement, next_index)?;
193 Ok(((first, second), next_index))
194 }
195}
196
197impl<T1: Bind, T2: Bind, T3: Bind> Bind for (T1, T2, T3) {
198 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
199 let next_index = self.0.bind(statement, start_index)?;
200 let next_index = self.1.bind(statement, next_index)?;
201 self.2.bind(statement, next_index)
202 }
203}
204
205impl<T1: Column, T2: Column, T3: Column> Column for (T1, T2, T3) {
206 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
207 let (first, next_index) = T1::column(statement, start_index)?;
208 let (second, next_index) = T2::column(statement, next_index)?;
209 let (third, next_index) = T3::column(statement, next_index)?;
210 Ok(((first, second, third), next_index))
211 }
212}
213
214impl<T1: Bind, T2: Bind, T3: Bind, T4: Bind> Bind for (T1, T2, T3, T4) {
215 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
216 let next_index = self.0.bind(statement, start_index)?;
217 let next_index = self.1.bind(statement, next_index)?;
218 let next_index = self.2.bind(statement, next_index)?;
219 self.3.bind(statement, next_index)
220 }
221}
222
223impl<T1: Column, T2: Column, T3: Column, T4: Column> Column for (T1, T2, T3, T4) {
224 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
225 let (first, next_index) = T1::column(statement, start_index)?;
226 let (second, next_index) = T2::column(statement, next_index)?;
227 let (third, next_index) = T3::column(statement, next_index)?;
228 let (fourth, next_index) = T4::column(statement, next_index)?;
229 Ok(((first, second, third, fourth), next_index))
230 }
231}
232
233impl<T1: Bind, T2: Bind, T3: Bind, T4: Bind, T5: Bind> Bind for (T1, T2, T3, T4, T5) {
234 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
235 let next_index = self.0.bind(statement, start_index)?;
236 let next_index = self.1.bind(statement, next_index)?;
237 let next_index = self.2.bind(statement, next_index)?;
238 let next_index = self.3.bind(statement, next_index)?;
239 self.4.bind(statement, next_index)
240 }
241}
242
243impl<T1: Column, T2: Column, T3: Column, T4: Column, T5: Column> Column for (T1, T2, T3, T4, T5) {
244 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
245 let (first, next_index) = T1::column(statement, start_index)?;
246 let (second, next_index) = T2::column(statement, next_index)?;
247 let (third, next_index) = T3::column(statement, next_index)?;
248 let (fourth, next_index) = T4::column(statement, next_index)?;
249 let (fifth, next_index) = T5::column(statement, next_index)?;
250 Ok(((first, second, third, fourth, fifth), next_index))
251 }
252}
253
254impl<T: Bind> Bind for Option<T> {
255 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
256 if let Some(this) = self {
257 this.bind(statement, start_index)
258 } else {
259 statement.bind_null(start_index)?;
260 Ok(start_index + 1)
261 }
262 }
263}
264
265impl<T: Column> Column for Option<T> {
266 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
267 if let SqlType::Null = statement.column_type(start_index)? {
268 Ok((None, start_index + 1))
269 } else {
270 T::column(statement, start_index).map(|(result, next_index)| (Some(result), next_index))
271 }
272 }
273}
274
275impl<T: Bind, const COUNT: usize> Bind for [T; COUNT] {
276 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
277 let mut current_index = start_index;
278 for binding in self {
279 current_index = binding.bind(statement, current_index)?
280 }
281
282 Ok(current_index)
283 }
284}
285
286impl<T: Column + Default + Copy, const COUNT: usize> Column for [T; COUNT] {
287 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
288 let mut array = [Default::default(); COUNT];
289 let mut current_index = start_index;
290 for i in 0..COUNT {
291 (array[i], current_index) = T::column(statement, current_index)?;
292 }
293 Ok((array, current_index))
294 }
295}
296
297impl<T: Bind> Bind for Vec<T> {
298 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
299 let mut current_index = start_index;
300 for binding in self.iter() {
301 current_index = binding.bind(statement, current_index)?
302 }
303
304 Ok(current_index)
305 }
306}
307
308impl<T: Bind> Bind for &[T] {
309 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
310 let mut current_index = start_index;
311 for binding in *self {
312 current_index = binding.bind(statement, current_index)?
313 }
314
315 Ok(current_index)
316 }
317}
318
319impl Bind for &Path {
320 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
321 self.as_os_str().as_bytes().bind(statement, start_index)
322 }
323}
324
325impl Bind for Arc<Path> {
326 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
327 self.as_ref().bind(statement, start_index)
328 }
329}
330
331impl Bind for PathBuf {
332 fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
333 (self.as_ref() as &Path).bind(statement, start_index)
334 }
335}
336
337impl Column for PathBuf {
338 fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
339 let blob = statement.column_blob(start_index)?;
340
341 Ok((
342 PathBuf::from(OsStr::from_bytes(blob).to_owned()),
343 start_index + 1,
344 ))
345 }
346}