Add support for toDate filter to parse more types of date-time strings

This commit is contained in:
Ashish Reddy 2025-10-03 16:28:30 +05:30
parent 1c0677d5f7
commit 8bc7fe72d0
No known key found for this signature in database
GPG Key ID: C304C8A92FA75541
2 changed files with 34 additions and 9 deletions

View File

@ -85,6 +85,10 @@ pub enum RunnerErrorKind {
error: String,
},
FilterDecode(String),
FilterDateParsingError {
date: String,
format: String,
},
FilterInvalidEncoding(String),
/// Input of the filter is not valid, with a given reason.
FilterInvalidInput(String),
@ -143,6 +147,7 @@ impl DisplaySourceError for RunnerError {
RunnerErrorKind::ExpressionInvalidType { .. } => "Invalid expression type".to_string(),
RunnerErrorKind::FileReadAccess { .. } => "File read access".to_string(),
RunnerErrorKind::FileWriteAccess { .. } => "File write access".to_string(),
RunnerErrorKind::FilterDateParsingError { .. } => "Filter error".to_string(),
RunnerErrorKind::FilterDecode { .. } => "Filter error".to_string(),
RunnerErrorKind::FilterInvalidEncoding { .. } => "Filter error".to_string(),
RunnerErrorKind::FilterInvalidInput { .. } => "Filter error".to_string(),
@ -233,6 +238,11 @@ impl DisplaySourceError for RunnerError {
let message = error::add_carets(message, self.source_info, content);
color_red_multiline_string(&message)
}
RunnerErrorKind::FilterDateParsingError { date, format } => {
let message = &format!("value <{date}> could not be parsed with <{format}> format");
let message = error::add_carets(message, self.source_info, content);
color_red_multiline_string(&message)
}
RunnerErrorKind::FilterDecode(encoding) => {
let message = &format!("value can not be decoded with <{encoding}> encoding");
let message = error::add_carets(message, self.source_info, content);

View File

@ -15,7 +15,7 @@
* limitations under the License.
*
*/
use chrono::NaiveDateTime;
use chrono::{DateTime, NaiveDate, NaiveDateTime, Utc};
use hurl_core::ast::{SourceInfo, Template};
use crate::runner::template::eval_template;
@ -33,15 +33,30 @@ pub fn eval_to_date(
let format = eval_template(format, variables)?;
match value {
Value::String(v) => match NaiveDateTime::parse_from_str(v, format.as_str()) {
Ok(v) => Ok(Some(Value::Date(
v.and_local_timezone(chrono::Utc).unwrap(),
))),
Err(_) => {
let kind = RunnerErrorKind::FilterInvalidInput(value.repr());
Err(RunnerError::new(source_info, kind, assert))
Value::String(v) => {
if let Ok(dt) = DateTime::parse_from_str(v, format.as_str()) {
return Ok(Some(Value::Date(dt.with_timezone(&Utc))));
}
},
if let Ok(dt) = NaiveDateTime::parse_from_str(v, format.as_str()) {
return Ok(Some(Value::Date(
DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc),
)));
}
if let Ok(date) = NaiveDate::parse_from_str(v, format.as_str()) {
let dt = date.and_hms_opt(0, 0, 0).unwrap();
return Ok(Some(Value::Date(
DateTime::<Utc>::from_naive_utc_and_offset(dt, Utc),
)));
}
let kind = RunnerErrorKind::FilterDateParsingError {
date: v.to_string(),
format,
};
Err(RunnerError::new(source_info, kind, assert))
}
v => {
let kind = RunnerErrorKind::FilterInvalidInput(v.repr());
Err(RunnerError::new(source_info, kind, assert))