Skip to content

Commit 8634f32

Browse files
committed
refactor(types): unify primitive and Result conversions with into_result
- introduce IntoResult to eliminate is_ok() + unwrap patterns - unify integer conversions using a single-line cast Signed-off-by: Florian Valeye <[email protected]>
1 parent acd7863 commit 8634f32

File tree

1 file changed

+48
-52
lines changed

1 file changed

+48
-52
lines changed

crates/duckdb/src/types/from_sql.rs

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -76,34 +76,26 @@ macro_rules! from_sql_integral(
7676
#[inline]
7777
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
7878
match value {
79-
// TODO: Update all cast operation same to HugeInt
80-
ValueRef::TinyInt(i) => Ok(<$t as cast::From<i8>>::cast(i).unwrap()),
81-
ValueRef::SmallInt(i) => Ok(<$t as cast::From<i16>>::cast(i).unwrap()),
82-
ValueRef::Int(i) => Ok(<$t as cast::From<i32>>::cast(i).unwrap()),
83-
ValueRef::BigInt(i) => Ok(<$t as cast::From<i64>>::cast(i).unwrap()),
84-
ValueRef::HugeInt(i) => {
85-
let v = <$t as cast::From<i128>>::cast(i);
86-
if v.is_ok() {
87-
Ok(v.unwrap())
88-
} else {
89-
Err(FromSqlError::OutOfRange(i))
90-
}
91-
},
79+
ValueRef::TinyInt(i) => <$t as cast::From<i8>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
80+
ValueRef::SmallInt(i) => <$t as cast::From<i16>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
81+
ValueRef::Int(i) => <$t as cast::From<i32>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
82+
ValueRef::BigInt(i) => <$t as cast::From<i64>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
83+
ValueRef::HugeInt(i) => <$t as cast::From<i128>>::cast(i).into_result(FromSqlError::OutOfRange(i)),
9284

93-
ValueRef::UTinyInt(i) => Ok(<$t as cast::From<u8>>::cast(i).unwrap()),
94-
ValueRef::USmallInt(i) => Ok(<$t as cast::From<u16>>::cast(i).unwrap()),
95-
ValueRef::UInt(i) => Ok(<$t as cast::From<u32>>::cast(i).unwrap()),
96-
ValueRef::UBigInt(i) => Ok(<$t as cast::From<u64>>::cast(i).unwrap()),
85+
ValueRef::UTinyInt(i) => <$t as cast::From<u8>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
86+
ValueRef::USmallInt(i) => <$t as cast::From<u16>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
87+
ValueRef::UInt(i) => <$t as cast::From<u32>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
88+
ValueRef::UBigInt(i) => <$t as cast::From<u64>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
9789

98-
ValueRef::Float(i) => Ok(<$t as cast::From<f32>>::cast(i).unwrap()),
99-
ValueRef::Double(i) => Ok(<$t as cast::From<f64>>::cast(i).unwrap()),
90+
ValueRef::Float(i) => <$t as cast::From<f32>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
91+
ValueRef::Double(i) => <$t as cast::From<f64>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
10092

10193
// TODO: more efficient way?
10294
ValueRef::Decimal(i) => Ok(i.to_string().parse::<$t>().unwrap()),
10395

104-
ValueRef::Timestamp(_, i) => Ok(<$t as cast::From<i64>>::cast(i).unwrap()),
105-
ValueRef::Date32(i) => Ok(<$t as cast::From<i32>>::cast(i).unwrap()),
106-
ValueRef::Time64(TimeUnit::Microsecond, i) => Ok(<$t as cast::From<i64>>::cast(i).unwrap()),
96+
ValueRef::Timestamp(_, i) => <$t as cast::From<i64>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
97+
ValueRef::Date32(i) => <$t as cast::From<i32>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
98+
ValueRef::Time64(TimeUnit::Microsecond, i) => <$t as cast::From<i64>>::cast(i).into_result(FromSqlError::OutOfRange(i as i128)),
10799
ValueRef::Text(_) => {
108100
let v = value.as_str()?.parse::<$t>();
109101
match v {
@@ -124,45 +116,49 @@ macro_rules! from_sql_integral(
124116
)
125117
);
126118

127-
/// A trait for to implement unwrap method for primitive types
128-
/// cast::From trait returns Result or the primitive, and for
129-
/// Result we need to unwrap() for the column_result function
130-
/// We implement unwrap() for all the primitive types so
131-
/// We can always call unwrap() for the cast() function.
132-
trait Unwrap {
133-
fn unwrap(self) -> Self;
134-
fn is_ok(&self) -> bool;
119+
/// A trait to provide ok_or method for both Result and primitive types
120+
/// cast::From trait returns Result or the primitive, depending on the types
121+
trait IntoResult {
122+
type Value;
123+
fn into_result<E>(self, err: E) -> Result<Self::Value, E>;
135124
}
136125

137-
macro_rules! unwrap_integral(
138-
($t:ident) => (
139-
impl Unwrap for $t {
140-
#[inline]
141-
fn unwrap(self) -> Self {
142-
self
143-
}
126+
/// A macro to implement the IntoResult trait for all integral types
127+
macro_rules! into_result_integral(
128+
($type_name:ident) => (
129+
impl IntoResult for $type_name {
130+
type Value = $type_name;
144131

145132
#[inline]
146-
fn is_ok(&self) -> bool {
147-
true
133+
fn into_result<E>(self, _err: E) -> Result<Self::Value, E> {
134+
Ok(self)
148135
}
149136
}
150137
)
151138
);
152139

153-
unwrap_integral!(i8);
154-
unwrap_integral!(i16);
155-
unwrap_integral!(i32);
156-
unwrap_integral!(i64);
157-
unwrap_integral!(i128);
158-
unwrap_integral!(isize);
159-
unwrap_integral!(u8);
160-
unwrap_integral!(u16);
161-
unwrap_integral!(u32);
162-
unwrap_integral!(u64);
163-
unwrap_integral!(usize);
164-
unwrap_integral!(f32);
165-
unwrap_integral!(f64);
140+
into_result_integral!(i8);
141+
into_result_integral!(i16);
142+
into_result_integral!(i32);
143+
into_result_integral!(i64);
144+
into_result_integral!(i128);
145+
into_result_integral!(isize);
146+
into_result_integral!(u8);
147+
into_result_integral!(u16);
148+
into_result_integral!(u32);
149+
into_result_integral!(u64);
150+
into_result_integral!(usize);
151+
into_result_integral!(f32);
152+
into_result_integral!(f64);
153+
154+
impl<T, E> IntoResult for Result<T, E> {
155+
type Value = T;
156+
157+
#[inline]
158+
fn into_result<E2>(self, err: E2) -> Result<Self::Value, E2> {
159+
self.map_err(|_| err)
160+
}
161+
}
166162

167163
from_sql_integral!(i8);
168164
from_sql_integral!(i16);

0 commit comments

Comments
 (0)