feat(napi): support chrono::NaiveDateTime (#1601)

This commit is contained in:
LongYinan 2023-05-26 18:28:34 +08:00 committed by GitHub
parent ab83d88c57
commit c6258cf633
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 1 deletions

View file

@ -161,6 +161,7 @@ static KNOWN_TYPES: Lazy<HashMap<&'static str, (&'static str, bool, bool)>> = La
("BigUint64Array", ("BigUint64Array", false, false)),
("DataView", ("DataView", false, false)),
("DateTime", ("Date", false, false)),
("NaiveDateTime", ("Date", false ,false)),
("Date", ("Date", false, false)),
("JsDate", ("Date", false, false)),
("JsBuffer", ("Buffer", false, false)),

View file

@ -1,4 +1,4 @@
use std::ptr;
use std::{ptr, str::FromStr};
use chrono::{DateTime, NaiveDateTime, Utc};
@ -29,6 +29,97 @@ impl ValidateNapiValue for DateTime<Utc> {
}
}
impl ToNapiValue for NaiveDateTime {
unsafe fn to_napi_value(env: sys::napi_env, val: NaiveDateTime) -> Result<sys::napi_value> {
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 `NaiveDateTime` into napi value",
)?;
Ok(ptr)
}
}
impl FromNapiValue for NaiveDateTime {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
let mut to_iso_string = ptr::null_mut();
check_status!(
unsafe {
napi_sys::napi_create_string_utf8(
env,
"toISOString\0".as_ptr().cast(),
11,
&mut to_iso_string,
)
},
"create toISOString JavaScript string failed"
)?;
let mut to_iso_string_method = ptr::null_mut();
check_status!(
unsafe { sys::napi_get_property(env, napi_val, to_iso_string, &mut to_iso_string_method) },
"get toISOString method failed"
)?;
let mut iso_string_value = ptr::null_mut();
check_status!(
unsafe {
sys::napi_call_function(
env,
napi_val,
to_iso_string_method,
0,
ptr::null(),
&mut iso_string_value,
)
},
"Call toISOString on Date Object failed"
)?;
let mut iso_string_length = 0;
check_status!(
unsafe {
sys::napi_get_value_string_utf8(
env,
iso_string_value,
ptr::null_mut(),
0,
&mut iso_string_length,
)
},
"Get ISOString length failed"
)?;
let mut iso_string = String::with_capacity(iso_string_length + 1);
check_status!(
unsafe {
sys::napi_get_value_string_utf8(
env,
iso_string_value,
iso_string.as_mut_ptr().cast(),
iso_string_length,
&mut iso_string_length,
)
},
"Get ISOString length failed"
)?;
unsafe { iso_string.as_mut_vec().set_len(iso_string_length) };
let naive = NaiveDateTime::from_str(iso_string.as_str()).map_err(|err| {
Error::new(
Status::InvalidArg,
format!(
"Failed to convert napi value into rust type `NaiveDateTime` {} {}",
err, iso_string
),
)
})?;
Ok(naive)
}
}
impl ToNapiValue for DateTime<Utc> {
unsafe fn to_napi_value(env: sys::napi_env, val: DateTime<Utc>) -> Result<sys::napi_value> {
let mut ptr = std::ptr::null_mut();

View file

@ -268,6 +268,10 @@ Generated by [AVA](https://avajs.dev).
export function chronoDateToMillis(input: Date): number␊
export function chronoNativeDateTime(date: Date): number␊
export function chronoNativeDateTimeReturn(): Date | null␊
export function concatLatin1(s: string): string␊
export function concatStr(s: string): string␊

View file

@ -130,6 +130,8 @@ import {
tsfnReturnPromise,
tsfnReturnPromiseTimeout,
returnFromSharedCrate,
chronoNativeDateTime,
chronoNativeDateTimeReturn,
} from '../'
test('export const', (t) => {
@ -980,3 +982,14 @@ Napi5Test('Class with getter setter closures', (t) => {
// @ts-expect-error
t.is(instance.age, 0.3)
})
Napi5Test('Date to chrono::NativeDateTime test', (t) => {
const fixture = new Date()
t.is(chronoNativeDateTime(fixture), fixture.valueOf())
})
Napi5Test('Date from chrono::NativeDateTime test', (t) => {
const fixture = chronoNativeDateTimeReturn()
t.true(fixture instanceof Date)
t.is(fixture?.toISOString(), '2016-12-23T15:25:59.325Z')
})

View file

@ -258,6 +258,10 @@ export function chronoDateAdd1Minute(input: Date): Date
export function chronoDateToMillis(input: Date): number
export function chronoNativeDateTime(date: Date): number
export function chronoNativeDateTimeReturn(): Date | null
export function concatLatin1(s: string): string
export function concatStr(s: string): string

View file

@ -1,3 +1,5 @@
use std::str::FromStr;
use chrono::{Duration, Utc};
use napi::bindgen_prelude::*;
@ -21,3 +23,13 @@ pub struct Dates {
pub start: chrono::DateTime<Utc>,
pub end: Option<chrono::DateTime<Utc>>,
}
#[napi]
pub fn chrono_native_date_time(date: chrono::NaiveDateTime) -> i64 {
date.timestamp_millis()
}
#[napi]
pub fn chrono_native_date_time_return() -> Option<chrono::NaiveDateTime> {
chrono::NaiveDateTime::from_str("2016-12-23T15:25:59.325").ok()
}