Skip to content

Commit

Permalink
Fail in strict mode if timestamp is outside of range
Browse files Browse the repository at this point in the history
  • Loading branch information
unexge committed Dec 31, 2023
1 parent 063f4b6 commit ce7584d
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions src/builtins/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) {
m.insert("time.weekday", (weekday, 1));
}

fn add_date(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
fn add_date(span: &Span, params: &[Ref<Expr>], args: &[Value], strict: bool) -> Result<Value> {
let name = "time.add_date";
ensure_args_count(span, name, params, args, 4)?;

Expand All @@ -50,7 +50,7 @@ fn add_date(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) ->
return Ok(Value::Undefined);
};

Ok(datetime
datetime
.with_year(new_year)
.and_then(|d| {
let rhs = Months::new(months.unsigned_abs());
Expand All @@ -68,9 +68,9 @@ fn add_date(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) ->
d.checked_sub_days(rhs)
}
})
.and_then(|d| d.timestamp_nanos_opt())
.map(Into::into)
.unwrap_or(Value::Undefined))
.map_or(Ok(Value::Undefined), |d| {
safe_timestamp_nanos(span, strict, d.timestamp_nanos_opt())
})
}

fn clock(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
Expand Down Expand Up @@ -179,48 +179,37 @@ fn format(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> R
Ok(Value::String(result.into()))
}

fn now_ns(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
fn now_ns(span: &Span, params: &[Ref<Expr>], args: &[Value], strict: bool) -> Result<Value> {
let name = "time.now_ns";
ensure_args_count(span, name, params, args, 0)?;

match Utc::now().timestamp_nanos_opt() {
Some(val) => Ok(Value::from(val)),
None => Ok(Value::Undefined),
}
safe_timestamp_nanos(span, strict, Utc::now().timestamp_nanos_opt())
}

fn parse_ns(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
fn parse_ns(span: &Span, params: &[Ref<Expr>], args: &[Value], strict: bool) -> Result<Value> {
let name = "time.parse_ns";
ensure_args_count(span, name, params, args, 2)?;

let layout = ensure_string(name, &params[0], &args[0])?;
let value = ensure_string(name, &params[1], &args[1])?;

let datetime = NaiveDateTime::parse_from_str(&value, &layout)?;

match datetime.timestamp_nanos_opt() {
Some(ns) => Ok(Value::Number(ns.into())),
None => Ok(Value::Undefined),
}
safe_timestamp_nanos(span, strict, datetime.timestamp_nanos_opt())
}

fn parse_rfc3339_ns(
span: &Span,
params: &[Ref<Expr>],
args: &[Value],
_strict: bool,
strict: bool,
) -> Result<Value> {
let name = "time.parse_rfc3339_ns";
ensure_args_count(span, name, params, args, 1)?;

let value = ensure_string(name, &params[0], &args[0])?;

let datetime = DateTime::parse_from_rfc3339(&value)?;

match datetime.timestamp_nanos_opt() {
Some(ns) => Ok(Value::Number(ns.into())),
None => Ok(Value::Undefined),
}
safe_timestamp_nanos(span, strict, datetime.timestamp_nanos_opt())
}

fn weekday(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) -> Result<Value> {
Expand All @@ -242,6 +231,16 @@ fn weekday(span: &Span, params: &[Ref<Expr>], args: &[Value], _strict: bool) ->
Ok(Value::String(weekday.into()))
}

fn safe_timestamp_nanos(span: &Span, strict: bool, nanos: Option<i64>) -> Result<Value> {
match nanos {
Some(ns) => Ok(Value::Number(ns.into())),
None if strict => {
bail!(span.error("time outside of valid range"))
}
None => Ok(Value::Undefined),
}
}

fn parse_epoch(
fcn: &str,
arg: &Expr,
Expand Down

0 comments on commit ce7584d

Please sign in to comment.