10
10
11
11
#![ cfg( feature = "frunk" ) ]
12
12
13
+ use std:: sync:: Arc ;
14
+
13
15
use frunk:: { hlist:: h_cons, prelude:: HList } ;
14
16
pub use frunk:: { HCons , HNil } ;
15
17
16
18
use super :: { FromRow , FromRowError } ;
17
19
use crate :: {
20
+ packets:: Column ,
18
21
row:: { new_row_raw, Row } ,
19
22
value:: {
20
23
convert:: { FromValue , FromValueError } ,
@@ -40,79 +43,49 @@ impl<H, T> FromRow for HCons<H, T>
40
43
where
41
44
H : FromValue ,
42
45
H :: Intermediate : Into < Value > ,
43
- T : FromRow + sealed :: HlistFromRow ,
46
+ T : FromRow ,
44
47
T : HList ,
45
48
{
46
49
fn from_row_opt ( row : Row ) -> Result < Self , FromRowError >
47
50
where
48
51
Self : Sized ,
49
52
{
50
- use sealed:: HlistFromRow ;
51
-
52
53
if row. len ( ) != Self :: LEN {
53
54
return Err ( FromRowError ( row) ) ;
54
55
}
55
56
56
57
let columns = row. columns ( ) ;
57
- let values = row. unwrap_raw ( ) ;
58
+ let mut values = row. unwrap_raw ( ) ;
58
59
59
- Self :: hlist_from_row_opt ( values)
60
- . map_err ( |values| FromRowError ( new_row_raw ( values, columns) ) )
61
- }
62
- }
60
+ debug_assert_eq ! ( values. len( ) , Self :: LEN ) ;
63
61
64
- mod sealed {
65
- use super :: * ;
62
+ let Some ( head) = values[ 0 ] . take ( ) else {
63
+ return Err ( FromRowError ( new_row_raw ( values, columns) ) ) ;
64
+ } ;
66
65
67
- /// Helper trait for `FromRow for HList`.
68
- pub trait HlistFromRow : Sized {
69
- fn hlist_from_row_opt ( values : Vec < Option < Value > > ) -> Result < Self , Vec < Option < Value > > > ;
70
- }
71
-
72
- impl HlistFromRow for HNil {
73
- fn hlist_from_row_opt ( values : Vec < Option < Value > > ) -> Result < Self , Vec < Option < Value > > > {
74
- debug_assert_eq ! ( values. len( ) , Self :: LEN ) ;
75
- Ok ( HNil )
76
- }
77
- }
78
-
79
- impl < H , T > HlistFromRow for HCons < H , T >
80
- where
81
- H : FromValue ,
82
- H :: Intermediate : Into < Value > ,
83
- T : HlistFromRow ,
84
- T : HList ,
85
- {
86
- fn hlist_from_row_opt ( mut values : Vec < Option < Value > > ) -> Result < Self , Vec < Option < Value > > >
87
- where
88
- Self : Sized ,
89
- {
90
- debug_assert_eq ! ( values. len( ) , Self :: LEN ) ;
91
-
92
- if values[ 0 ] . is_none ( ) {
93
- return Err ( values) ;
66
+ let ir = match H :: get_intermediate ( head) {
67
+ Ok ( ir) => ir,
68
+ Err ( FromValueError ( value) ) => {
69
+ values[ 0 ] = Some ( value) ;
70
+ return Err ( FromRowError ( new_row_raw ( values, columns) ) ) ;
71
+ }
72
+ } ;
73
+
74
+ // TODO: Avoid cloning columns here by using something like `owning_ref::ArcRef`
75
+ let columns_tail: Arc < [ Column ] > =
76
+ columns. iter ( ) . skip ( 1 ) . cloned ( ) . collect :: < Vec < _ > > ( ) . into ( ) ;
77
+ values. remove ( 0 ) ;
78
+
79
+ let tail = match T :: from_row_opt ( new_row_raw ( values, columns_tail) ) {
80
+ Ok ( x) => x,
81
+ Err ( FromRowError ( row) ) => {
82
+ let mut values = row. unwrap_raw ( ) ;
83
+ values. insert ( 0 , Some ( ir. into ( ) ) ) ;
84
+ return Err ( FromRowError ( new_row_raw ( values, columns) ) ) ;
94
85
}
86
+ } ;
95
87
96
- let head = values. remove ( 0 ) . expect ( "must be here" ) ;
97
-
98
- let ir = match H :: get_intermediate ( head) {
99
- Ok ( ir) => ir,
100
- Err ( FromValueError ( value) ) => {
101
- values. insert ( 0 , Some ( value) ) ;
102
- return Err ( values) ;
103
- }
104
- } ;
105
-
106
- let tail = match T :: hlist_from_row_opt ( values) {
107
- Ok ( t) => t,
108
- Err ( mut values) => {
109
- values. insert ( 0 , Some ( Into :: < Value > :: into ( ir) ) ) ;
110
- return Err ( values) ;
111
- }
112
- } ;
113
-
114
- Ok ( h_cons ( Into :: < H > :: into ( ir) , tail) )
115
- }
88
+ Ok ( h_cons ( Into :: < H > :: into ( ir) , tail) )
116
89
}
117
90
}
118
91
0 commit comments