From eca7e87129fd69ef82b59016f1ae7ecb578d9fdf Mon Sep 17 00:00:00 2001 From: discord9 <55937128+discord9@users.noreply.github.com> Date: Thu, 24 Aug 2023 10:44:13 +0800 Subject: [PATCH] chore: try from value (#2236) * chore: try from value * chore: add TryFromValueError variant --- src/datatypes/src/error.rs | 3 ++ src/datatypes/src/value.rs | 60 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/datatypes/src/error.rs b/src/datatypes/src/error.rs index e5b701e13f..211e3a4052 100644 --- a/src/datatypes/src/error.rs +++ b/src/datatypes/src/error.rs @@ -115,6 +115,9 @@ pub enum Error { #[snafu(display("Column {} already exists", column))] DuplicateColumn { column: String, location: Location }, + + #[snafu(display("Failed to unpack value to given type: {}", reason))] + TryFromValue { reason: String, location: Location }, } impl ErrorExt for Error { diff --git a/src/datatypes/src/value.rs b/src/datatypes/src/value.rs index 9f154d65c3..4d672a8cea 100644 --- a/src/datatypes/src/value.rs +++ b/src/datatypes/src/value.rs @@ -32,7 +32,7 @@ use serde::{Deserialize, Serialize}; use snafu::{ensure, ResultExt}; use crate::error; -use crate::error::Result; +use crate::error::{Error, Result, TryFromValueSnafu}; use crate::prelude::*; use crate::type_id::LogicalTypeId; use crate::types::{IntervalType, ListType}; @@ -441,6 +441,62 @@ impl Ord for Value { } } +macro_rules! impl_try_from_value { + ($Variant: ident, $Type: ident) => { + impl TryFrom for $Type { + type Error = Error; + + #[inline] + fn try_from(from: Value) -> std::result::Result { + match from { + Value::$Variant(v) => Ok(v.into()), + _ => TryFromValueSnafu { + reason: format!("{:?} is not a {}", from, stringify!($Type)), + } + .fail(), + } + } + } + + impl TryFrom for Option<$Type> { + type Error = Error; + + #[inline] + fn try_from(from: Value) -> std::result::Result { + match from { + Value::$Variant(v) => Ok(Some(v.into())), + Value::Null => Ok(None), + _ => TryFromValueSnafu { + reason: format!("{:?} is not a {}", from, stringify!($Type)), + } + .fail(), + } + } + } + }; +} + +impl_try_from_value!(Boolean, bool); +impl_try_from_value!(UInt8, u8); +impl_try_from_value!(UInt16, u16); +impl_try_from_value!(UInt32, u32); +impl_try_from_value!(UInt64, u64); +impl_try_from_value!(Int8, i8); +impl_try_from_value!(Int16, i16); +impl_try_from_value!(Int32, i32); +impl_try_from_value!(Int64, i64); +impl_try_from_value!(Float32, f32); +impl_try_from_value!(Float64, f64); +impl_try_from_value!(Float32, OrderedF32); +impl_try_from_value!(Float64, OrderedF64); +impl_try_from_value!(String, StringBytes); +impl_try_from_value!(Binary, Bytes); +impl_try_from_value!(Date, Date); +impl_try_from_value!(Time, Time); +impl_try_from_value!(DateTime, DateTime); +impl_try_from_value!(Timestamp, Timestamp); +impl_try_from_value!(Interval, Interval); + macro_rules! impl_value_from { ($Variant: ident, $Type: ident) => { impl From<$Type> for Value { @@ -471,6 +527,8 @@ impl_value_from!(Int32, i32); impl_value_from!(Int64, i64); impl_value_from!(Float32, f32); impl_value_from!(Float64, f64); +impl_value_from!(Float32, OrderedF32); +impl_value_from!(Float64, OrderedF64); impl_value_from!(String, StringBytes); impl_value_from!(Binary, Bytes); impl_value_from!(Date, Date);