From 6a9ae1322de02f212bff9bea3d2ffb26f1a1530e Mon Sep 17 00:00:00 2001 From: sup39 Date: Mon, 29 Apr 2024 18:50:39 +0900 Subject: [PATCH] feat(napi): implement From/ToNapiValue for chrono::DateTime and chrono::DateTime (#1902) --- .../src/bindgen_runtime/js_values/date.rs | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/crates/napi/src/bindgen_runtime/js_values/date.rs b/crates/napi/src/bindgen_runtime/js_values/date.rs index 13fd4a73..20f8f06a 100644 --- a/crates/napi/src/bindgen_runtime/js_values/date.rs +++ b/crates/napi/src/bindgen_runtime/js_values/date.rs @@ -1,10 +1,10 @@ use std::{ptr, str::FromStr}; -use chrono::{DateTime, NaiveDateTime, Utc}; +use chrono::{DateTime, Local, LocalResult, NaiveDateTime, TimeZone}; use crate::{bindgen_prelude::*, check_status, sys, ValueType}; -impl TypeName for DateTime { +impl TypeName for DateTime { fn type_name() -> &'static str { "DateTime" } @@ -14,7 +14,7 @@ impl TypeName for DateTime { } } -impl ValidateNapiValue for DateTime { +impl ValidateNapiValue for DateTime { unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result { let mut is_date = false; check_status!(unsafe { sys::napi_is_date(env, napi_val, &mut is_date) })?; @@ -120,39 +120,38 @@ impl FromNapiValue for NaiveDateTime { } } -impl ToNapiValue for DateTime { - unsafe fn to_napi_value(env: sys::napi_env, val: DateTime) -> Result { +impl ToNapiValue for DateTime { + unsafe fn to_napi_value(env: sys::napi_env, val: DateTime) -> Result { let mut ptr = std::ptr::null_mut(); let millis_since_epoch_utc = val.timestamp_millis() as f64; check_status!( unsafe { sys::napi_create_date(env, millis_since_epoch_utc, &mut ptr) }, - "Failed to convert rust type `DateTime` into napi value", + "Failed to convert rust type `DateTime` into napi value", )?; Ok(ptr) } } -impl FromNapiValue for DateTime { +impl FromNapiValue for DateTime +where + DateTime: From>, +{ unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { let mut milliseconds_since_epoch_utc = 0.0; check_status!( unsafe { sys::napi_get_date_value(env, napi_val, &mut milliseconds_since_epoch_utc) }, - "Failed to convert napi value into rust type `DateTime`", + "Failed to convert napi value into rust type `DateTime`", )?; - let milliseconds_since_epoch_utc = milliseconds_since_epoch_utc as i64; - let timestamp_seconds = milliseconds_since_epoch_utc / 1_000; - let naive = DateTime::from_timestamp( - timestamp_seconds, - (milliseconds_since_epoch_utc % 1_000 * 1_000_000) as u32, - ) - .ok_or_else(|| Error::new(Status::DateExpected, "Found invalid date".to_owned()))?; - Ok(DateTime::::from_naive_utc_and_offset( - naive.naive_utc(), - Utc, - )) + match Local.timestamp_millis_opt(milliseconds_since_epoch_utc as i64) { + LocalResult::Single(dt) => Ok(dt.into()), + _ => Err(Error::new( + Status::DateExpected, + "Found invalid date".to_owned(), + )), + } } }