Skip to content

Commit 7a0b692

Browse files
committed
Get rid of HlistFromRow helper trait
1 parent 5b8ca87 commit 7a0b692

File tree

1 file changed

+30
-57
lines changed

1 file changed

+30
-57
lines changed

src/row/convert/frunk.rs

Lines changed: 30 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010
1111
#![cfg(feature = "frunk")]
1212

13+
use std::sync::Arc;
14+
1315
use frunk::{hlist::h_cons, prelude::HList};
1416
pub use frunk::{HCons, HNil};
1517

1618
use super::{FromRow, FromRowError};
1719
use crate::{
20+
packets::Column,
1821
row::{new_row_raw, Row},
1922
value::{
2023
convert::{FromValue, FromValueError},
@@ -40,79 +43,49 @@ impl<H, T> FromRow for HCons<H, T>
4043
where
4144
H: FromValue,
4245
H::Intermediate: Into<Value>,
43-
T: FromRow + sealed::HlistFromRow,
46+
T: FromRow,
4447
T: HList,
4548
{
4649
fn from_row_opt(row: Row) -> Result<Self, FromRowError>
4750
where
4851
Self: Sized,
4952
{
50-
use sealed::HlistFromRow;
51-
5253
if row.len() != Self::LEN {
5354
return Err(FromRowError(row));
5455
}
5556

5657
let columns = row.columns();
57-
let values = row.unwrap_raw();
58+
let mut values = row.unwrap_raw();
5859

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);
6361

64-
mod sealed {
65-
use super::*;
62+
let Some(head) = values[0].take() else {
63+
return Err(FromRowError(new_row_raw(values, columns)));
64+
};
6665

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)));
9485
}
86+
};
9587

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))
11689
}
11790
}
11891

0 commit comments

Comments
 (0)