From 6ffb03216fffa7faa821e685c28798ac8d46f08f Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 2 Aug 2024 16:03:26 +0300 Subject: [PATCH] core/datetime: Simplify error handling --- core/datetime.rs | 117 +++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 85 deletions(-) diff --git a/core/datetime.rs b/core/datetime.rs index 7f31c0dab..a5170050c 100644 --- a/core/datetime.rs +++ b/core/datetime.rs @@ -1,24 +1,6 @@ use crate::types::OwnedValue; +use crate::Result; use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc}; -use std::result::Result; -use std::{error::Error, fmt::Display}; - -#[derive(Debug)] -enum DateTimeError { - InvalidArgument(String), - Other(String), -} - -impl Display for DateTimeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - DateTimeError::InvalidArgument(s) => write!(f, "Invalid argument: {}", s), - DateTimeError::Other(s) => write!(f, "Other error: {}", s), - } - } -} - -impl Error for DateTimeError {} fn get_max_datetime_exclusive() -> NaiveDateTime { // The maximum date in SQLite is 9999-12-31 @@ -28,51 +10,32 @@ fn get_max_datetime_exclusive() -> NaiveDateTime { ) } -pub fn get_date_from_time_value(time_value: &OwnedValue) -> crate::Result { +pub fn get_date_from_time_value(time_value: &OwnedValue) -> Result { let dt = parse_naive_date_time(time_value); - if dt.is_ok() { - return Ok(get_date_from_naive_datetime(dt.unwrap())); - } else { - match dt.unwrap_err() { - DateTimeError::InvalidArgument(_) => { - Ok(String::new()) - } - DateTimeError::Other(s) => { - Err(crate::error::LimboError::InvalidDate(s)) - } - } + match dt { + Some(dt) => Ok(get_date_from_naive_datetime(dt)), + None => Ok(String::new()), } } -pub fn get_time_from_datetime_value(time_value: &OwnedValue) -> crate::Result { +pub fn get_time_from_datetime_value(time_value: &OwnedValue) -> Result { let dt = parse_naive_date_time(time_value); - if dt.is_ok() { - return Ok(get_time_from_naive_datetime(dt.unwrap())); - } else { - match dt.unwrap_err() { - DateTimeError::InvalidArgument(_) => { - Ok(String::new()) - } - DateTimeError::Other(s) => { - Err(crate::error::LimboError::InvalidTime(s)) - } - } + match dt { + Some(dt) => Ok(get_time_from_naive_datetime(dt)), + None => Ok(String::new()), } } -fn parse_naive_date_time(time_value: &OwnedValue) -> Result { +fn parse_naive_date_time(time_value: &OwnedValue) -> Option { match time_value { OwnedValue::Text(s) => get_date_time_from_time_value_string(s), OwnedValue::Integer(i) => get_date_time_from_time_value_integer(*i), OwnedValue::Float(f) => get_date_time_from_time_value_float(*f), - _ => Err(DateTimeError::InvalidArgument(format!( - "Invalid time value: {}", - time_value - ))), + _ => None, } } -fn get_date_time_from_time_value_string(value: &str) -> Result { +fn get_date_time_from_time_value_string(value: &str) -> Option { // Time-value formats: // 1-7. YYYY-MM-DD[THH:MM[:SS[.SSS]]] // 8-10. HH:MM[:SS[.SSS]] @@ -83,7 +46,7 @@ fn get_date_time_from_time_value_string(value: &str) -> Result Result Result Result { +fn parse_datetime_with_optional_tz(value: &str, format: &str) -> Option { // Try parsing with timezone let with_tz_format = format.to_owned() + "%:z"; if let Ok(dt) = DateTime::parse_from_str(value, &with_tz_format) { - return Ok(dt.with_timezone(&Utc).naive_utc()); + return Some(dt.with_timezone(&Utc).naive_utc()); } let mut value_without_tz = value; @@ -147,36 +103,27 @@ fn parse_datetime_with_optional_tz( } // Parse without timezone - NaiveDateTime::parse_from_str(value_without_tz, format) - .map_err(|_| DateTimeError::InvalidArgument(format!("Invalid time value: {}", value))) + if let Ok(dt) = NaiveDateTime::parse_from_str(value_without_tz, format) { + return Some(dt); + } + None } -fn get_date_time_from_time_value_integer(value: i64) -> Result { +fn get_date_time_from_time_value_integer(value: i64) -> Option { i32::try_from(value).map_or_else( - |_| { - Err(DateTimeError::InvalidArgument(format!( - "Invalid julian day: {}", - value - ))) - }, + |_| None, |value| get_date_time_from_time_value_float(value as f64), ) } -fn get_date_time_from_time_value_float(value: f64) -> Result { - if value.is_infinite() - || value.is_nan() - || value < 0.0 - || value >= 5373484.5 - { - return Err(DateTimeError::InvalidArgument(format!( - "Invalid julian day: {}", - value - ))); +fn get_date_time_from_time_value_float(value: f64) -> Option { + if value.is_infinite() || value.is_nan() || value < 0.0 || value >= 5373484.5 { + return None; + } + match julian_day_converter::julian_day_to_datetime(value) { + Ok(dt) => Some(dt), + Err(_) => None, } - let dt = julian_day_converter::julian_day_to_datetime(value) - .map_err(|_| DateTimeError::Other("Failed parsing the julian date".to_string()))?; - Ok(dt) } fn is_leap_second(dt: &NaiveDateTime) -> bool {