1use crate::{
10 row::Row,
11 value::{
12 convert::{FromValue, FromValueError},
13 Value,
14 },
15};
16
17use std::{any::type_name, error::Error, fmt};
18
19pub mod frunk;
20
21#[derive(Debug, Clone, PartialEq)]
23pub struct FromRowError(pub Row);
24
25impl fmt::Display for FromRowError {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 write!(
28 f,
29 "Couldn't convert the row `{:?}` to a desired type",
30 self.0
31 )
32 }
33}
34
35impl Error for FromRowError {
36 fn description(&self) -> &str {
37 "Couldn't convert the row to a desired type"
38 }
39}
40
41pub fn from_row<T: FromRow>(row: Row) -> T {
43 FromRow::from_row(row)
44}
45
46pub fn from_row_opt<T: FromRow>(row: Row) -> Result<T, FromRowError> {
48 FromRow::from_row_opt(row)
49}
50
51pub trait FromRow {
78 fn from_row(row: Row) -> Self
79 where
80 Self: Sized,
81 {
82 match Self::from_row_opt(row) {
83 Ok(x) => x,
84 Err(FromRowError(row)) => panic!(
85 "Couldn't convert {:?} to type {}. (see FromRow documentation)",
86 row,
87 type_name::<Self>(),
88 ),
89 }
90 }
91
92 fn from_row_opt(row: Row) -> Result<Self, FromRowError>
93 where
94 Self: Sized;
95}
96
97macro_rules! take_or_place {
98 ($row:expr, $index:expr, $t:ident) => (
99 match $row.take($index) {
100 Some(value) => {
101 match $t::get_intermediate(value) {
102 Ok(ir) => ir,
103 Err(FromValueError(value)) => {
104 $row.place($index, value);
105 return Err(FromRowError($row));
106 },
107 }
108 },
109 None => return Err(FromRowError($row)),
110 }
111 );
112 ($row:expr, $index:expr, $t:ident, $( [$idx:expr, $ir:expr] ),*) => (
113 match $row.take($index) {
114 Some(value) => {
115 match $t::get_intermediate(value) {
116 Ok(ir) => ir,
117 Err(FromValueError(value)) => {
118 $($row.place($idx, Into::<Value>::into($ir));)*
119 $row.place($index, value);
120 return Err(FromRowError($row));
121 },
122 }
123 },
124 None => return Err(FromRowError($row)),
125 }
126 );
127}
128
129impl FromRow for Row {
130 fn from_row(row: Row) -> Self {
131 row
132 }
133
134 fn from_row_opt(row: Row) -> Result<Self, FromRowError>
135 where
136 Self: Sized,
137 {
138 Ok(row)
139 }
140}
141
142impl<T> FromRow for T
143where
144 T: FromValue,
145{
146 fn from_row_opt(mut row: Row) -> Result<T, FromRowError> {
147 if row.len() == 1 {
148 Ok(take_or_place!(row, 0, T).into())
149 } else {
150 Err(FromRowError(row))
151 }
152 }
153}
154
155impl<T1> FromRow for (T1,)
156where
157 T1: FromValue,
158{
159 fn from_row_opt(mut row: Row) -> Result<(T1,), FromRowError> {
160 if row.len() == 1 {
161 Ok((take_or_place!(row, 0, T1).into(),))
162 } else {
163 Err(FromRowError(row))
164 }
165 }
166}
167
168impl<T1, T2> FromRow for (T1, T2)
169where
170 T1: FromValue,
171 T2: FromValue,
172 T1::Intermediate: Into<Value>,
173{
174 fn from_row_opt(mut row: Row) -> Result<(T1, T2), FromRowError> {
175 if row.len() != 2 {
176 return Err(FromRowError(row));
177 }
178 let ir1 = take_or_place!(row, 0, T1);
179 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
180 Ok((Into::<T1>::into(ir1), Into::<T2>::into(ir2)))
181 }
182}
183
184impl<T1, T2, T3> FromRow for (T1, T2, T3)
185where
186 T1: FromValue,
187 T2: FromValue,
188 T3: FromValue,
189 T1::Intermediate: Into<Value>,
190 T2::Intermediate: Into<Value>,
191{
192 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3), FromRowError> {
193 if row.len() != 3 {
194 return Err(FromRowError(row));
195 }
196 let ir1 = take_or_place!(row, 0, T1);
197 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
198 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
199 Ok((Into::<T1>::into(ir1), Into::<T2>::into(ir2), ir3.into()))
200 }
201}
202
203impl<T1, T2, T3, T4> FromRow for (T1, T2, T3, T4)
204where
205 T1: FromValue,
206 T2: FromValue,
207 T3: FromValue,
208 T4: FromValue,
209 T1::Intermediate: Into<Value>,
210 T2::Intermediate: Into<Value>,
211 T3::Intermediate: Into<Value>,
212{
213 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3, T4), FromRowError> {
214 if row.len() != 4 {
215 return Err(FromRowError(row));
216 }
217 let ir1 = take_or_place!(row, 0, T1);
218 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
219 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
220 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
221 Ok((
222 Into::<T1>::into(ir1),
223 Into::<T2>::into(ir2),
224 Into::<T3>::into(ir3),
225 ir4.into(),
226 ))
227 }
228}
229
230impl<T1, T2, T3, T4, T5> FromRow for (T1, T2, T3, T4, T5)
231where
232 T1: FromValue,
233 T2: FromValue,
234 T3: FromValue,
235 T4: FromValue,
236 T5: FromValue,
237 T1::Intermediate: Into<Value>,
238 T2::Intermediate: Into<Value>,
239 T3::Intermediate: Into<Value>,
240 T4::Intermediate: Into<Value>,
241{
242 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3, T4, T5), FromRowError> {
243 if row.len() != 5 {
244 return Err(FromRowError(row));
245 }
246 let ir1 = take_or_place!(row, 0, T1);
247 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
248 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
249 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
250 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
251 Ok((
252 Into::<T1>::into(ir1),
253 Into::<T2>::into(ir2),
254 Into::<T3>::into(ir3),
255 Into::<T4>::into(ir4),
256 ir5.into(),
257 ))
258 }
259}
260
261impl<T1, T2, T3, T4, T5, T6> FromRow for (T1, T2, T3, T4, T5, T6)
262where
263 T1: FromValue,
264 T2: FromValue,
265 T3: FromValue,
266 T4: FromValue,
267 T5: FromValue,
268 T6: FromValue,
269 T1::Intermediate: Into<Value>,
270 T2::Intermediate: Into<Value>,
271 T3::Intermediate: Into<Value>,
272 T4::Intermediate: Into<Value>,
273 T5::Intermediate: Into<Value>,
274{
275 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3, T4, T5, T6), FromRowError> {
276 if row.len() != 6 {
277 return Err(FromRowError(row));
278 }
279 let ir1 = take_or_place!(row, 0, T1);
280 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
281 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
282 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
283 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
284 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
285 Ok((
286 Into::<T1>::into(ir1),
287 Into::<T2>::into(ir2),
288 Into::<T3>::into(ir3),
289 Into::<T4>::into(ir4),
290 Into::<T5>::into(ir5),
291 ir6.into(),
292 ))
293 }
294}
295
296impl<T1, T2, T3, T4, T5, T6, T7> FromRow for (T1, T2, T3, T4, T5, T6, T7)
297where
298 T1: FromValue,
299 T2: FromValue,
300 T3: FromValue,
301 T4: FromValue,
302 T5: FromValue,
303 T6: FromValue,
304 T7: FromValue,
305 T1::Intermediate: Into<Value>,
306 T2::Intermediate: Into<Value>,
307 T3::Intermediate: Into<Value>,
308 T4::Intermediate: Into<Value>,
309 T5::Intermediate: Into<Value>,
310 T6::Intermediate: Into<Value>,
311{
312 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3, T4, T5, T6, T7), FromRowError> {
313 if row.len() != 7 {
314 return Err(FromRowError(row));
315 }
316 let ir1 = take_or_place!(row, 0, T1);
317 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
318 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
319 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
320 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
321 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
322 let ir7 = take_or_place!(
323 row,
324 6,
325 T7,
326 [0, ir1],
327 [1, ir2],
328 [2, ir3],
329 [3, ir4],
330 [4, ir5],
331 [5, ir6]
332 );
333 Ok((
334 Into::<T1>::into(ir1),
335 Into::<T2>::into(ir2),
336 Into::<T3>::into(ir3),
337 Into::<T4>::into(ir4),
338 Into::<T5>::into(ir5),
339 Into::<T6>::into(ir6),
340 ir7.into(),
341 ))
342 }
343}
344
345impl<T1, T2, T3, T4, T5, T6, T7, T8> FromRow for (T1, T2, T3, T4, T5, T6, T7, T8)
346where
347 T1: FromValue,
348 T2: FromValue,
349 T3: FromValue,
350 T4: FromValue,
351 T5: FromValue,
352 T6: FromValue,
353 T7: FromValue,
354 T8: FromValue,
355 T1::Intermediate: Into<Value>,
356 T2::Intermediate: Into<Value>,
357 T3::Intermediate: Into<Value>,
358 T4::Intermediate: Into<Value>,
359 T5::Intermediate: Into<Value>,
360 T6::Intermediate: Into<Value>,
361 T7::Intermediate: Into<Value>,
362{
363 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3, T4, T5, T6, T7, T8), FromRowError> {
364 if row.len() != 8 {
365 return Err(FromRowError(row));
366 }
367 let ir1 = take_or_place!(row, 0, T1);
368 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
369 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
370 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
371 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
372 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
373 let ir7 = take_or_place!(
374 row,
375 6,
376 T7,
377 [0, ir1],
378 [1, ir2],
379 [2, ir3],
380 [3, ir4],
381 [4, ir5],
382 [5, ir6]
383 );
384 let ir8 = take_or_place!(
385 row,
386 7,
387 T8,
388 [0, ir1],
389 [1, ir2],
390 [2, ir3],
391 [3, ir4],
392 [4, ir5],
393 [5, ir6],
394 [6, ir7]
395 );
396 Ok((
397 Into::<T1>::into(ir1),
398 Into::<T2>::into(ir2),
399 Into::<T3>::into(ir3),
400 Into::<T4>::into(ir4),
401 Into::<T5>::into(ir5),
402 Into::<T6>::into(ir6),
403 Into::<T7>::into(ir7),
404 ir8.into(),
405 ))
406 }
407}
408
409impl<T1, T2, T3, T4, T5, T6, T7, T8, T9> FromRow for (T1, T2, T3, T4, T5, T6, T7, T8, T9)
410where
411 T1: FromValue,
412 T2: FromValue,
413 T3: FromValue,
414 T4: FromValue,
415 T5: FromValue,
416 T6: FromValue,
417 T7: FromValue,
418 T8: FromValue,
419 T9: FromValue,
420 T1::Intermediate: Into<Value>,
421 T2::Intermediate: Into<Value>,
422 T3::Intermediate: Into<Value>,
423 T4::Intermediate: Into<Value>,
424 T5::Intermediate: Into<Value>,
425 T6::Intermediate: Into<Value>,
426 T7::Intermediate: Into<Value>,
427 T8::Intermediate: Into<Value>,
428{
429 fn from_row_opt(mut row: Row) -> Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9), FromRowError> {
430 if row.len() != 9 {
431 return Err(FromRowError(row));
432 }
433 let ir1 = take_or_place!(row, 0, T1);
434 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
435 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
436 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
437 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
438 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
439 let ir7 = take_or_place!(
440 row,
441 6,
442 T7,
443 [0, ir1],
444 [1, ir2],
445 [2, ir3],
446 [3, ir4],
447 [4, ir5],
448 [5, ir6]
449 );
450 let ir8 = take_or_place!(
451 row,
452 7,
453 T8,
454 [0, ir1],
455 [1, ir2],
456 [2, ir3],
457 [3, ir4],
458 [4, ir5],
459 [5, ir6],
460 [6, ir7]
461 );
462 let ir9 = take_or_place!(
463 row,
464 8,
465 T9,
466 [0, ir1],
467 [1, ir2],
468 [2, ir3],
469 [3, ir4],
470 [4, ir5],
471 [5, ir6],
472 [6, ir7],
473 [7, ir8]
474 );
475 Ok((
476 Into::<T1>::into(ir1),
477 Into::<T2>::into(ir2),
478 Into::<T3>::into(ir3),
479 Into::<T4>::into(ir4),
480 Into::<T5>::into(ir5),
481 Into::<T6>::into(ir6),
482 Into::<T7>::into(ir7),
483 Into::<T8>::into(ir8),
484 ir9.into(),
485 ))
486 }
487}
488
489impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> FromRow for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
490where
491 T1: FromValue,
492 T2: FromValue,
493 T3: FromValue,
494 T4: FromValue,
495 T5: FromValue,
496 T6: FromValue,
497 T7: FromValue,
498 T8: FromValue,
499 T9: FromValue,
500 T10: FromValue,
501 T1::Intermediate: Into<Value>,
502 T2::Intermediate: Into<Value>,
503 T3::Intermediate: Into<Value>,
504 T4::Intermediate: Into<Value>,
505 T5::Intermediate: Into<Value>,
506 T6::Intermediate: Into<Value>,
507 T7::Intermediate: Into<Value>,
508 T8::Intermediate: Into<Value>,
509 T9::Intermediate: Into<Value>,
510{
511 fn from_row_opt(
512 mut row: Row,
513 ) -> Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), FromRowError> {
514 if row.len() != 10 {
515 return Err(FromRowError(row));
516 }
517 let ir1 = take_or_place!(row, 0, T1);
518 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
519 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
520 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
521 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
522 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
523 let ir7 = take_or_place!(
524 row,
525 6,
526 T7,
527 [0, ir1],
528 [1, ir2],
529 [2, ir3],
530 [3, ir4],
531 [4, ir5],
532 [5, ir6]
533 );
534 let ir8 = take_or_place!(
535 row,
536 7,
537 T8,
538 [0, ir1],
539 [1, ir2],
540 [2, ir3],
541 [3, ir4],
542 [4, ir5],
543 [5, ir6],
544 [6, ir7]
545 );
546 let ir9 = take_or_place!(
547 row,
548 8,
549 T9,
550 [0, ir1],
551 [1, ir2],
552 [2, ir3],
553 [3, ir4],
554 [4, ir5],
555 [5, ir6],
556 [6, ir7],
557 [7, ir8]
558 );
559 let ir10 = take_or_place!(
560 row,
561 9,
562 T10,
563 [0, ir1],
564 [1, ir2],
565 [2, ir3],
566 [3, ir4],
567 [4, ir5],
568 [5, ir6],
569 [6, ir7],
570 [7, ir8],
571 [8, ir9]
572 );
573 Ok((
574 Into::<T1>::into(ir1),
575 Into::<T2>::into(ir2),
576 Into::<T3>::into(ir3),
577 Into::<T4>::into(ir4),
578 Into::<T5>::into(ir5),
579 Into::<T6>::into(ir6),
580 Into::<T7>::into(ir7),
581 Into::<T8>::into(ir8),
582 Into::<T9>::into(ir9),
583 ir10.into(),
584 ))
585 }
586}
587
588impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> FromRow
589 for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
590where
591 T1: FromValue,
592 T2: FromValue,
593 T3: FromValue,
594 T4: FromValue,
595 T5: FromValue,
596 T6: FromValue,
597 T7: FromValue,
598 T8: FromValue,
599 T9: FromValue,
600 T10: FromValue,
601 T11: FromValue,
602 T1::Intermediate: Into<Value>,
603 T2::Intermediate: Into<Value>,
604 T3::Intermediate: Into<Value>,
605 T4::Intermediate: Into<Value>,
606 T5::Intermediate: Into<Value>,
607 T6::Intermediate: Into<Value>,
608 T7::Intermediate: Into<Value>,
609 T8::Intermediate: Into<Value>,
610 T9::Intermediate: Into<Value>,
611 T10::Intermediate: Into<Value>,
612{
613 fn from_row_opt(
614 mut row: Row,
615 ) -> Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), FromRowError> {
616 if row.len() != 11 {
617 return Err(FromRowError(row));
618 }
619 let ir1 = take_or_place!(row, 0, T1);
620 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
621 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
622 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
623 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
624 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
625 let ir7 = take_or_place!(
626 row,
627 6,
628 T7,
629 [0, ir1],
630 [1, ir2],
631 [2, ir3],
632 [3, ir4],
633 [4, ir5],
634 [5, ir6]
635 );
636 let ir8 = take_or_place!(
637 row,
638 7,
639 T8,
640 [0, ir1],
641 [1, ir2],
642 [2, ir3],
643 [3, ir4],
644 [4, ir5],
645 [5, ir6],
646 [6, ir7]
647 );
648 let ir9 = take_or_place!(
649 row,
650 8,
651 T9,
652 [0, ir1],
653 [1, ir2],
654 [2, ir3],
655 [3, ir4],
656 [4, ir5],
657 [5, ir6],
658 [6, ir7],
659 [7, ir8]
660 );
661 let ir10 = take_or_place!(
662 row,
663 9,
664 T10,
665 [0, ir1],
666 [1, ir2],
667 [2, ir3],
668 [3, ir4],
669 [4, ir5],
670 [5, ir6],
671 [6, ir7],
672 [7, ir8],
673 [8, ir9]
674 );
675 let ir11 = take_or_place!(
676 row,
677 10,
678 T11,
679 [0, ir1],
680 [1, ir2],
681 [2, ir3],
682 [3, ir4],
683 [4, ir5],
684 [5, ir6],
685 [6, ir7],
686 [7, ir8],
687 [8, ir9],
688 [9, ir10]
689 );
690 Ok((
691 Into::<T1>::into(ir1),
692 Into::<T2>::into(ir2),
693 Into::<T3>::into(ir3),
694 Into::<T4>::into(ir4),
695 Into::<T5>::into(ir5),
696 Into::<T6>::into(ir6),
697 Into::<T7>::into(ir7),
698 Into::<T8>::into(ir8),
699 Into::<T9>::into(ir9),
700 Into::<T10>::into(ir10),
701 ir11.into(),
702 ))
703 }
704}
705
706impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> FromRow
707 for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)
708where
709 T1: FromValue,
710 T2: FromValue,
711 T3: FromValue,
712 T4: FromValue,
713 T5: FromValue,
714 T6: FromValue,
715 T7: FromValue,
716 T8: FromValue,
717 T9: FromValue,
718 T10: FromValue,
719 T11: FromValue,
720 T12: FromValue,
721 T1::Intermediate: Into<Value>,
722 T2::Intermediate: Into<Value>,
723 T3::Intermediate: Into<Value>,
724 T4::Intermediate: Into<Value>,
725 T5::Intermediate: Into<Value>,
726 T6::Intermediate: Into<Value>,
727 T7::Intermediate: Into<Value>,
728 T8::Intermediate: Into<Value>,
729 T9::Intermediate: Into<Value>,
730 T10::Intermediate: Into<Value>,
731 T11::Intermediate: Into<Value>,
732{
733 fn from_row_opt(
734 mut row: Row,
735 ) -> Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12), FromRowError> {
736 if row.len() != 12 {
737 return Err(FromRowError(row));
738 }
739 let ir1 = take_or_place!(row, 0, T1);
740 let ir2 = take_or_place!(row, 1, T2, [0, ir1]);
741 let ir3 = take_or_place!(row, 2, T3, [0, ir1], [1, ir2]);
742 let ir4 = take_or_place!(row, 3, T4, [0, ir1], [1, ir2], [2, ir3]);
743 let ir5 = take_or_place!(row, 4, T5, [0, ir1], [1, ir2], [2, ir3], [3, ir4]);
744 let ir6 = take_or_place!(row, 5, T6, [0, ir1], [1, ir2], [2, ir3], [3, ir4], [4, ir5]);
745 let ir7 = take_or_place!(
746 row,
747 6,
748 T7,
749 [0, ir1],
750 [1, ir2],
751 [2, ir3],
752 [3, ir4],
753 [4, ir5],
754 [5, ir6]
755 );
756 let ir8 = take_or_place!(
757 row,
758 7,
759 T8,
760 [0, ir1],
761 [1, ir2],
762 [2, ir3],
763 [3, ir4],
764 [4, ir5],
765 [5, ir6],
766 [6, ir7]
767 );
768 let ir9 = take_or_place!(
769 row,
770 8,
771 T9,
772 [0, ir1],
773 [1, ir2],
774 [2, ir3],
775 [3, ir4],
776 [4, ir5],
777 [5, ir6],
778 [6, ir7],
779 [7, ir8]
780 );
781 let ir10 = take_or_place!(
782 row,
783 9,
784 T10,
785 [0, ir1],
786 [1, ir2],
787 [2, ir3],
788 [3, ir4],
789 [4, ir5],
790 [5, ir6],
791 [6, ir7],
792 [7, ir8],
793 [8, ir9]
794 );
795 let ir11 = take_or_place!(
796 row,
797 10,
798 T11,
799 [0, ir1],
800 [1, ir2],
801 [2, ir3],
802 [3, ir4],
803 [4, ir5],
804 [5, ir6],
805 [6, ir7],
806 [7, ir8],
807 [8, ir9],
808 [9, ir10]
809 );
810 let ir12 = take_or_place!(
811 row,
812 11,
813 T12,
814 [0, ir1],
815 [1, ir2],
816 [2, ir3],
817 [3, ir4],
818 [4, ir5],
819 [5, ir6],
820 [6, ir7],
821 [7, ir8],
822 [8, ir9],
823 [9, ir10],
824 [10, ir11]
825 );
826 Ok((
827 Into::<T1>::into(ir1),
828 Into::<T2>::into(ir2),
829 Into::<T3>::into(ir3),
830 Into::<T4>::into(ir4),
831 Into::<T5>::into(ir5),
832 Into::<T6>::into(ir6),
833 Into::<T7>::into(ir7),
834 Into::<T8>::into(ir8),
835 Into::<T9>::into(ir9),
836 Into::<T10>::into(ir10),
837 Into::<T11>::into(ir11),
838 ir12.into(),
839 ))
840 }
841}
842
843#[cfg(feature = "nightly")]
844#[bench]
845fn bench_from_row(bencher: &mut test::Bencher) {
846 use std::sync::Arc;
847
848 use crate::{constants::ColumnType, io::WriteMysqlExt, packets::Column, value::Value};
849
850 fn col(name: &str, ty: ColumnType) -> Column {
851 let mut payload = b"\x00def".to_vec();
852 for _ in 0..5 {
853 payload.write_lenenc_str(name.as_bytes()).unwrap();
854 }
855 payload.extend_from_slice(&b"_\x2d\x00\xff\xff\xff\xff"[..]);
856 payload.push(ty as u8);
857 payload.extend_from_slice(&b"\x00\x00\x00"[..]);
858 Column::read(&payload[..]).unwrap()
859 }
860
861 let row = Row {
862 values: vec![
863 Some(Value::Bytes(b"12.3456789".to_vec())),
864 Some(Value::Int(0xF0)),
865 Some(Value::Int(0xF000)),
866 Some(Value::Int(0xF0000000)),
867 ],
868 columns: Arc::from(
869 vec![
870 col("foo", ColumnType::MYSQL_TYPE_STRING),
871 col("foo", ColumnType::MYSQL_TYPE_TINY),
872 col("foo", ColumnType::MYSQL_TYPE_SHORT),
873 col("foo", ColumnType::MYSQL_TYPE_LONG),
874 ]
875 .into_boxed_slice(),
876 ),
877 };
878
879 bencher.iter(|| from_row::<(String, u8, u16, u32)>(row.clone()));
880}