feat(napi): support chrono::NaiveDateTime (#1601)
This commit is contained in:
parent
ab83d88c57
commit
c6258cf633
7 changed files with 126 additions and 1 deletions
|
@ -161,6 +161,7 @@ static KNOWN_TYPES: Lazy<HashMap<&'static str, (&'static str, bool, bool)>> = La
|
||||||
("BigUint64Array", ("BigUint64Array", false, false)),
|
("BigUint64Array", ("BigUint64Array", false, false)),
|
||||||
("DataView", ("DataView", false, false)),
|
("DataView", ("DataView", false, false)),
|
||||||
("DateTime", ("Date", false, false)),
|
("DateTime", ("Date", false, false)),
|
||||||
|
("NaiveDateTime", ("Date", false ,false)),
|
||||||
("Date", ("Date", false, false)),
|
("Date", ("Date", false, false)),
|
||||||
("JsDate", ("Date", false, false)),
|
("JsDate", ("Date", false, false)),
|
||||||
("JsBuffer", ("Buffer", false, false)),
|
("JsBuffer", ("Buffer", false, false)),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ptr;
|
use std::{ptr, str::FromStr};
|
||||||
|
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
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> {
|
impl ToNapiValue for DateTime<Utc> {
|
||||||
unsafe fn to_napi_value(env: sys::napi_env, val: DateTime<Utc>) -> Result<sys::napi_value> {
|
unsafe fn to_napi_value(env: sys::napi_env, val: DateTime<Utc>) -> Result<sys::napi_value> {
|
||||||
let mut ptr = std::ptr::null_mut();
|
let mut ptr = std::ptr::null_mut();
|
||||||
|
|
|
@ -268,6 +268,10 @@ Generated by [AVA](https://avajs.dev).
|
||||||
␊
|
␊
|
||||||
export function chronoDateToMillis(input: Date): number␊
|
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 concatLatin1(s: string): string␊
|
||||||
␊
|
␊
|
||||||
export function concatStr(s: string): string␊
|
export function concatStr(s: string): string␊
|
||||||
|
|
Binary file not shown.
|
@ -130,6 +130,8 @@ import {
|
||||||
tsfnReturnPromise,
|
tsfnReturnPromise,
|
||||||
tsfnReturnPromiseTimeout,
|
tsfnReturnPromiseTimeout,
|
||||||
returnFromSharedCrate,
|
returnFromSharedCrate,
|
||||||
|
chronoNativeDateTime,
|
||||||
|
chronoNativeDateTimeReturn,
|
||||||
} from '../'
|
} from '../'
|
||||||
|
|
||||||
test('export const', (t) => {
|
test('export const', (t) => {
|
||||||
|
@ -980,3 +982,14 @@ Napi5Test('Class with getter setter closures', (t) => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
t.is(instance.age, 0.3)
|
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')
|
||||||
|
})
|
||||||
|
|
4
examples/napi/index.d.ts
vendored
4
examples/napi/index.d.ts
vendored
|
@ -258,6 +258,10 @@ export function chronoDateAdd1Minute(input: Date): Date
|
||||||
|
|
||||||
export function chronoDateToMillis(input: Date): number
|
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 concatLatin1(s: string): string
|
||||||
|
|
||||||
export function concatStr(s: string): string
|
export function concatStr(s: string): string
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use napi::bindgen_prelude::*;
|
use napi::bindgen_prelude::*;
|
||||||
|
|
||||||
|
@ -21,3 +23,13 @@ pub struct Dates {
|
||||||
pub start: chrono::DateTime<Utc>,
|
pub start: chrono::DateTime<Utc>,
|
||||||
pub end: Option<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()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue