1use crate::row::{Row, TryFromColumn, DefaultConfiguration, TryFromRow, RowConvertError};
2use crate::value::{TryFromValue, Value};
3use std::convert::Infallible;
4use std::error::Error;
5use std::fmt;
6
7pub type ValueRow = Vec<Option<Value>>;
11
12impl TryFromRow<DefaultConfiguration> for ValueRow {
13 type Error = RowConvertError;
14
15 fn try_from_row<'r, 's, 'c, S>(mut row: Row<'r, 's, 'c, S, DefaultConfiguration>) -> Result<Self, Self::Error> {
16 let mut value_row = Vec::with_capacity(row.columns() as usize);
17
18 loop {
19 if let Some(column) = row.shift_column() {
20 let value: Option<Value> = TryFromColumn::try_from_column(column)?;
21 value_row.push(value)
22 } else {
23 return Ok(value_row);
24 }
25 }
26 }
27}
28
29pub trait TryFromValueRow: Sized {
39 type Error: Error + 'static;
40 fn try_from_value_row(values: ValueRow) -> Result<Self, Self::Error>;
42}
43
44#[derive(Debug)]
46pub enum ValueRowConvertError {
47 UnexpectedNullValue(&'static str),
48 UnexpectedValue,
49 UnexpectedNumberOfColumns { expected: u16, got: usize },
50 ValueConvertError(Box<dyn Error>),
51}
52
53impl fmt::Display for ValueRowConvertError {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 match self {
56 ValueRowConvertError::UnexpectedNullValue(t) => {
57 write!(f, "expecting value of type {} but got NULL", t)
58 }
59 ValueRowConvertError::UnexpectedValue => write!(f, "expecting no data (unit) but got a row"),
60 ValueRowConvertError::UnexpectedNumberOfColumns { expected, got } => write!(
61 f,
62 "unexpected number of columns: expected {} but got {}",
63 expected, got
64 ),
65 ValueRowConvertError::ValueConvertError(_) => {
66 write!(f, "failed to convert column value to target type")
67 }
68 }
69 }
70}
71
72impl Error for ValueRowConvertError {
73 fn source(&self) -> Option<&(dyn Error + 'static)> {
74 match self {
75 ValueRowConvertError::UnexpectedNullValue(_)
76 | ValueRowConvertError::UnexpectedValue
77 | ValueRowConvertError::UnexpectedNumberOfColumns { .. } => None,
78 ValueRowConvertError::ValueConvertError(err) => Some(err.as_ref()),
79 }
80 }
81}
82
83impl TryFromValueRow for ValueRow {
85 type Error = Infallible;
86 fn try_from_value_row(values: ValueRow) -> Result<Self, Self::Error> {
87 Ok(values)
88 }
89}
90
91impl TryFromValueRow for () {
93 type Error = ValueRowConvertError;
94 fn try_from_value_row(_values: ValueRow) -> Result<Self, Self::Error> {
95 Err(ValueRowConvertError::UnexpectedValue)
96 }
97}
98
99impl<T> TryFromValueRow for T
101where
102 T: TryFromValue,
103{
104 type Error = ValueRowConvertError;
105 fn try_from_value_row(mut values: ValueRow) -> Result<Self, Self::Error> {
106 if values.len() != 1 {
107 return Err(ValueRowConvertError::UnexpectedNumberOfColumns {
108 expected: 1,
109 got: values.len(),
110 });
111 }
112 values
113 .pop()
114 .ok_or_else(|| ValueRowConvertError::UnexpectedNullValue("Value"))
115 .and_then(|v| {
116 TryFromValue::try_from_value(v)
117 .map_err(|e| ValueRowConvertError::ValueConvertError(Box::new(e)))
118 })
119 }
120}
121
122#[derive(Debug)]
124pub enum ValueRowConvertTupleError {
125 UnexpectedNumberOfColumns { expected: u16, tuple: &'static str },
126 ValueConvertError(Box<dyn Error>),
127}
128
129impl fmt::Display for ValueRowConvertTupleError {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 match self {
132 ValueRowConvertTupleError::UnexpectedNumberOfColumns { expected, tuple } => write!(
133 f,
134 "failed to convert row with {} columns to tuple {}",
135 expected, tuple
136 ),
137 ValueRowConvertTupleError::ValueConvertError(_) => {
138 write!(f, "failed to convert column value to target type")
139 }
140 }
141 }
142}
143
144impl Error for ValueRowConvertTupleError {
145 fn source(&self) -> Option<&(dyn Error + 'static)> {
146 match self {
147 ValueRowConvertTupleError::UnexpectedNumberOfColumns { .. } => None,
148 ValueRowConvertTupleError::ValueConvertError(err) => Some(err.as_ref()),
149 }
150 }
151}
152
153macro_rules! count {
154 () => (0usize);
155 ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
156}
157
158macro_rules! try_from_tuple {
159 ($(
160 $Tuple:ident {
161 $(($idx:tt) -> $T:ident)+
162 }
163 )+) => {
164 $(
165 impl<$($T: TryFromValue),+> TryFromValueRow for ($($T,)+) {
166 type Error = ValueRowConvertTupleError;
167 fn try_from_value_row(values: ValueRow) -> Result<($($T,)+), Self::Error> {
168 if values.len() != count!($($T)+) {
169 return Err(ValueRowConvertTupleError::UnexpectedNumberOfColumns { expected: values.len() as u16, tuple: stringify![($($T,)+)] })
170 }
171 let mut values = values.into_iter();
172 Ok(($({ let x: $T = $T::try_from_value(values.next().unwrap()).map_err(|err| ValueRowConvertTupleError::ValueConvertError(Box::new(err)))?; x},)+))
173 }
174 }
175 )+
176 }
177}
178
179try_from_tuple! {
180 Tuple1 {
181 (0) -> A
182 }
183 Tuple2 {
184 (0) -> A
185 (1) -> B
186 }
187 Tuple3 {
188 (0) -> A
189 (1) -> B
190 (2) -> C
191 }
192 Tuple4 {
193 (0) -> A
194 (1) -> B
195 (2) -> C
196 (3) -> D
197 }
198 Tuple5 {
199 (0) -> A
200 (1) -> B
201 (2) -> C
202 (3) -> D
203 (4) -> E
204 }
205 Tuple6 {
206 (0) -> A
207 (1) -> B
208 (2) -> C
209 (3) -> D
210 (4) -> E
211 (5) -> F
212 }
213 Tuple7 {
214 (0) -> A
215 (1) -> B
216 (2) -> C
217 (3) -> D
218 (4) -> E
219 (5) -> F
220 (6) -> G
221 }
222 Tuple8 {
223 (0) -> A
224 (1) -> B
225 (2) -> C
226 (3) -> D
227 (4) -> E
228 (5) -> F
229 (6) -> G
230 (7) -> H
231 }
232 Tuple9 {
233 (0) -> A
234 (1) -> B
235 (2) -> C
236 (3) -> D
237 (4) -> E
238 (5) -> F
239 (6) -> G
240 (7) -> H
241 (8) -> I
242 }
243 Tuple10 {
244 (0) -> A
245 (1) -> B
246 (2) -> C
247 (3) -> D
248 (4) -> E
249 (5) -> F
250 (6) -> G
251 (7) -> H
252 (8) -> I
253 (9) -> J
254 }
255 Tuple11 {
256 (0) -> A
257 (1) -> B
258 (2) -> C
259 (3) -> D
260 (4) -> E
261 (5) -> F
262 (6) -> G
263 (7) -> H
264 (8) -> I
265 (9) -> J
266 (10) -> K
267 }
268 Tuple12 {
269 (0) -> A
270 (1) -> B
271 (2) -> C
272 (3) -> D
273 (4) -> E
274 (5) -> F
275 (6) -> G
276 (7) -> H
277 (8) -> I
278 (9) -> J
279 (10) -> K
280 (11) -> L
281 }
282 Tuple13 {
283 (0) -> A
284 (1) -> B
285 (2) -> C
286 (3) -> D
287 (4) -> E
288 (5) -> F
289 (6) -> G
290 (7) -> H
291 (8) -> I
292 (9) -> J
293 (10) -> K
294 (11) -> L
295 (13) -> M
296 }
297 Tuple14 {
298 (0) -> A
299 (1) -> B
300 (2) -> C
301 (3) -> D
302 (4) -> E
303 (5) -> F
304 (6) -> G
305 (7) -> H
306 (8) -> I
307 (9) -> J
308 (10) -> K
309 (11) -> L
310 (13) -> M
311 (14) -> N
312 }
313 Tuple15 {
314 (0) -> A
315 (1) -> B
316 (2) -> C
317 (3) -> D
318 (4) -> E
319 (5) -> F
320 (6) -> G
321 (7) -> H
322 (8) -> I
323 (9) -> J
324 (10) -> K
325 (11) -> L
326 (13) -> M
327 (14) -> N
328 (15) -> O
329 }
330 Tuple16 {
331 (0) -> A
332 (1) -> B
333 (2) -> C
334 (3) -> D
335 (4) -> E
336 (5) -> F
337 (6) -> G
338 (7) -> H
339 (8) -> I
340 (9) -> J
341 (10) -> K
342 (11) -> L
343 (13) -> M
344 (14) -> N
345 (15) -> O
346 (16) -> P
347 }
348 Tuple17 {
349 (0) -> A
350 (1) -> B
351 (2) -> C
352 (3) -> D
353 (4) -> E
354 (5) -> F
355 (6) -> G
356 (7) -> H
357 (8) -> I
358 (9) -> J
359 (10) -> K
360 (11) -> L
361 (13) -> M
362 (14) -> N
363 (15) -> O
364 (16) -> P
365 (17) -> Q
366 }
367 Tuple18 {
368 (0) -> A
369 (1) -> B
370 (2) -> C
371 (3) -> D
372 (4) -> E
373 (5) -> F
374 (6) -> G
375 (7) -> H
376 (8) -> I
377 (9) -> J
378 (10) -> K
379 (11) -> L
380 (13) -> M
381 (14) -> N
382 (15) -> O
383 (16) -> P
384 (17) -> Q
385 (18) -> R
386 }
387 Tuple19 {
388 (0) -> A
389 (1) -> B
390 (2) -> C
391 (3) -> D
392 (4) -> E
393 (5) -> F
394 (6) -> G
395 (7) -> H
396 (8) -> I
397 (9) -> J
398 (10) -> K
399 (11) -> L
400 (13) -> M
401 (14) -> N
402 (15) -> O
403 (16) -> P
404 (17) -> Q
405 (18) -> R
406 (19) -> S
407 }
408 Tuple20 {
409 (0) -> A
410 (1) -> B
411 (2) -> C
412 (3) -> D
413 (4) -> E
414 (5) -> F
415 (6) -> G
416 (7) -> H
417 (8) -> I
418 (9) -> J
419 (10) -> K
420 (11) -> L
421 (13) -> M
422 (14) -> N
423 (15) -> O
424 (16) -> P
425 (17) -> Q
426 (18) -> R
427 (19) -> S
428 (20) -> T
429 }
430 Tuple21 {
431 (0) -> A
432 (1) -> B
433 (2) -> C
434 (3) -> D
435 (4) -> E
436 (5) -> F
437 (6) -> G
438 (7) -> H
439 (8) -> I
440 (9) -> J
441 (10) -> K
442 (11) -> L
443 (13) -> M
444 (14) -> N
445 (15) -> O
446 (16) -> P
447 (17) -> Q
448 (18) -> R
449 (19) -> S
450 (20) -> T
451 (21) -> U
452 }
453 Tuple22 {
454 (0) -> A
455 (1) -> B
456 (2) -> C
457 (3) -> D
458 (4) -> E
459 (5) -> F
460 (6) -> G
461 (7) -> H
462 (8) -> I
463 (9) -> J
464 (10) -> K
465 (11) -> L
466 (13) -> M
467 (14) -> N
468 (15) -> O
469 (16) -> P
470 (17) -> Q
471 (18) -> R
472 (19) -> S
473 (20) -> T
474 (21) -> U
475 (22) -> V
476 }
477 Tuple23 {
478 (0) -> A
479 (1) -> B
480 (2) -> C
481 (3) -> D
482 (4) -> E
483 (5) -> F
484 (6) -> G
485 (7) -> H
486 (8) -> I
487 (9) -> J
488 (10) -> K
489 (11) -> L
490 (13) -> M
491 (14) -> N
492 (15) -> O
493 (16) -> P
494 (17) -> Q
495 (18) -> R
496 (19) -> S
497 (20) -> T
498 (21) -> U
499 (22) -> V
500 (23) -> W
501 }
502 Tuple24 {
503 (0) -> A
504 (1) -> B
505 (2) -> C
506 (3) -> D
507 (4) -> E
508 (5) -> F
509 (6) -> G
510 (7) -> H
511 (8) -> I
512 (9) -> J
513 (10) -> K
514 (11) -> L
515 (13) -> M
516 (14) -> N
517 (15) -> O
518 (16) -> P
519 (17) -> Q
520 (18) -> R
521 (19) -> S
522 (20) -> T
523 (21) -> U
524 (22) -> V
525 (23) -> W
526 (24) -> Y
527 }
528}
529
530#[cfg(test)]
531mod tests {
532 #[allow(unused_imports)]
533 use super::*;
534 #[allow(unused_imports)]
535 use crate::Odbc;
536 #[allow(unused_imports)]
537 use assert_matches::assert_matches;
538
539 #[derive(Debug)]
540 struct Foo {
541 val: i64,
542 }
543
544 impl TryFromValueRow for Foo {
545 type Error = Infallible;
546 fn try_from_value_row(mut values: ValueRow) -> Result<Self, Self::Error> {
547 Ok(values
548 .pop()
549 .map(|val| Foo {
550 val: val.and_then(|v| v.to_i64()).expect("val to be an bigint"),
551 })
552 .expect("value"))
553 }
554 }
555
556 use crate::value::Value;
557
558 #[test]
559 fn test_custom_type() {
560 let test_row: ValueRow = vec![Some(Value::Bigint(42))];
561 let foo: Foo = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
562
563 assert_eq!(foo.val, 42);
564 }
565
566 #[test]
567 fn test_single_value() {
568 let test_row: ValueRow = vec![Some(Value::Bigint(42))];
569 let value: Value = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
570
571 assert_eq!(value.to_i64().unwrap(), 42);
572 }
573
574 #[test]
575 fn test_single_nullable_value() {
576 let test_row: ValueRow = vec![Some(Value::Bigint(42))];
577 let value: Option<Value> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
578
579 assert!(value.is_some());
580 assert_eq!(value.unwrap().to_i64().unwrap(), 42);
581
582 let test_row: ValueRow = vec![None];
583 let value: Option<Value> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
584
585 assert!(value.is_none());
586 }
587
588 #[test]
589 fn test_value_row() {
590 let test_row: ValueRow = vec![Some(Value::Bigint(42)), Some(Value::Integer(22))];
591 let value: ValueRow = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
592
593 assert_eq!(value.len(), 2);
594 assert_eq!(value[0].as_ref().unwrap().to_i64().unwrap(), 42);
595 assert_eq!(value[1].as_ref().unwrap().to_i32().unwrap(), 22);
596 }
597
598 #[test]
599 fn test_single_copy() {
600 let test_row: ValueRow = vec![Some(Value::Bit(true))];
601 let value: bool = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
602
603 assert_eq!(value, true);
604
605 let test_row: ValueRow = vec![Some(Value::Bit(true))];
606 let value: Option<bool> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
607
608 assert_eq!(value.unwrap(), true);
609
610 let test_row: ValueRow = vec![None];
611 let value: Option<bool> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
612
613 assert!(value.is_none());
614
615 let test_row: ValueRow = vec![Some(Value::Bigint(42))];
616 let value: i64 = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
617
618 assert_eq!(value, 42);
619
620 let test_row: ValueRow = vec![Some(Value::Bigint(42))];
621 let value: Option<i64> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
622
623 assert_eq!(value.unwrap(), 42i64);
624
625 let test_row: ValueRow = vec![None];
626 let value: Option<i64> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
627
628 assert!(value.is_none());
629 }
630
631 #[test]
632 fn test_single_unsigned() {
633 let test_row: ValueRow = vec![Some(Value::Bigint(42))];
634 let value: Option<u64> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
635
636 assert_eq!(value.unwrap(), 42u64);
637 }
638
639 #[test]
640 #[should_panic(expected = "ValueOutOfRange")]
641 fn test_single_unsigned_err() {
642 let test_row: ValueRow = vec![Some(Value::Bigint(-666))];
643 let _value: Option<u64> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
644 }
645
646 #[test]
647 fn test_single_string() {
648 let test_row: ValueRow = vec![Some(Value::String("foo".into()))];
649 let value: String = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
650
651 assert_eq!(&value, "foo");
652
653 let test_row: ValueRow = vec![Some(Value::String("foo".into()))];
654 let value: Option<String> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
655
656 assert_eq!(&value.unwrap(), "foo");
657
658 let test_row: ValueRow = vec![None];
659 let value: Option<String> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
660
661 assert!(value.is_none());
662 }
663
664 #[test]
665 #[cfg(feature = "chrono")]
666 fn test_single_date() {
667 use chrono::Datelike;
668 use chrono::NaiveDate;
669
670 let test_row: ValueRow = vec![Some(Value::Date(odbc::SqlDate { year: 2019, month: 4, day: 2 }))];
671 let value: NaiveDate = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
672
673 assert_eq!(value.year(), 2019);
674 assert_eq!(value.month(), 4);
675 assert_eq!(value.day(), 2);
676
677 let test_row: ValueRow = vec![Some(Value::Date(odbc::SqlDate { year: 2019, month: 4, day: 2 }))];
678 let value: Option<NaiveDate> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
679
680 assert_eq!(value.unwrap().year(), 2019);
681 assert_eq!(value.unwrap().month(), 4);
682 assert_eq!(value.unwrap().day(), 2);
683
684 let test_row: ValueRow = vec![None];
685 let value: Option<NaiveDate> = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
686
687 assert!(value.is_none());
688 }
689
690 #[test]
691 fn test_tuple_value() {
692 let test_row: ValueRow = vec![Some(Value::String("foo".into())), Some(Value::Bigint(42)), Some(Value::Bit(true))];
693 let value: (String, i64, bool) = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
694
695 assert_eq!(&value.0, "foo");
696 assert_eq!(value.1, 42);
697 assert_eq!(value.2, true);
698
699 let test_row: ValueRow = vec![Some(Value::String("foo".into())), Some(Value::Bigint(42)), Some(Value::Bit(true))];
700 let value: (Option<String>, i64, Option<bool>) = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
701
702 assert_eq!(&value.0.unwrap(), "foo");
703 assert_eq!(value.1, 42);
704 assert_eq!(value.2.unwrap(), true);
705
706 let test_row: ValueRow = vec![None, Some(Value::Bigint(42)), None];
707 let value: (Option<String>, i64, Option<bool>) = TryFromValueRow::try_from_value_row(test_row).expect("failed to convert");
708
709 assert!(&value.0.is_none());
710 assert_eq!(value.1, 42);
711 assert!(value.2.is_none());
712 }
713
714 #[test]
715 fn test_value_row_conversions() {
716 let test_row: ValueRow = vec![Some(Value::Bit(true)), Some(Value::Integer(42)), None];
717 type Test = (Option<bool>, Option<u32>, Option<String>);
718
719 let (b, u, s) = Test::try_from_value_row(test_row).unwrap();
721 assert_eq!(b, Some(true));
722 assert_eq!(u, Some(42));
723 assert_eq!(s, None);
724 }
725}