From 65fe29c8540fe04b92ad12e8bba6adeae37b58a3 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 8 May 2025 13:20:09 +0800 Subject: [PATCH] refactor!(napi): add lifetime to JsString (#2614) --- bench/src/create_array.rs | 6 +-- .../src/bindgen_runtime/js_values/either.rs | 6 +-- .../bindgen_runtime/js_values/promise_raw.rs | 4 +- crates/napi/src/env.rs | 12 ++--- crates/napi/src/error.rs | 10 ++--- crates/napi/src/js_values/de.rs | 27 +++++------- crates/napi/src/js_values/function.rs | 4 +- crates/napi/src/js_values/global.rs | 12 ++--- crates/napi/src/js_values/mod.rs | 42 ++++++++++-------- crates/napi/src/js_values/number.rs | 2 +- crates/napi/src/js_values/ser.rs | 27 +++++++----- crates/napi/src/js_values/string/latin1.rs | 10 ++--- crates/napi/src/js_values/string/mod.rs | 44 ++++++++++++++----- crates/napi/src/js_values/string/utf16.rs | 16 +++---- crates/napi/src/js_values/string/utf8.rs | 12 ++--- examples/napi-compat-mode/src/env.rs | 2 +- examples/napi-compat-mode/src/function.rs | 6 +-- 17 files changed, 131 insertions(+), 111 deletions(-) diff --git a/bench/src/create_array.rs b/bench/src/create_array.rs index 9dc89ac6..78c87aba 100644 --- a/bench/src/create_array.rs +++ b/bench/src/create_array.rs @@ -1,4 +1,4 @@ -use napi::{ContextlessResult, Env, JsObject, JsString, Result, Unknown}; +use napi::{ContextlessResult, Env, JsObject, Result, Unknown}; use serde_json::to_string; pub fn register_js(exports: &mut JsObject) -> Result<()> { @@ -9,10 +9,10 @@ pub fn register_js(exports: &mut JsObject) -> Result<()> { } #[contextless_function] -pub fn create_array_json(env: Env) -> ContextlessResult { +pub fn create_array_json(_: Env) -> ContextlessResult { let a: Vec = vec![42; 1000]; let arr_string = to_string(&a)?; - env.create_string(arr_string.as_str()).map(Some) + Ok(Some(arr_string)) } #[contextless_function] diff --git a/crates/napi/src/bindgen_runtime/js_values/either.rs b/crates/napi/src/bindgen_runtime/js_values/either.rs index 07b568fc..fe66cbdc 100644 --- a/crates/napi/src/bindgen_runtime/js_values/either.rs +++ b/crates/napi/src/bindgen_runtime/js_values/either.rs @@ -120,10 +120,10 @@ macro_rules! either_n { } } - impl< $( $parameter ),+ > $either_name < $( $parameter ),+ > - where $( $parameter: JsValue ),+ + impl<'env, $( $parameter ),+ > $either_name < $( $parameter ),+ > + where $( $parameter: JsValue<'env> ),+ { - pub fn as_unknown(&self) -> Unknown { + pub fn as_unknown(&self) -> Unknown<'env> { match &self { $( Self:: $parameter (v) => v.to_unknown() ),+ } diff --git a/crates/napi/src/bindgen_runtime/js_values/promise_raw.rs b/crates/napi/src/bindgen_runtime/js_values/promise_raw.rs index 773b4c3f..41ed4200 100644 --- a/crates/napi/src/bindgen_runtime/js_values/promise_raw.rs +++ b/crates/napi/src/bindgen_runtime/js_values/promise_raw.rs @@ -15,7 +15,7 @@ pub struct PromiseRaw<'env, T> { _phantom: &'env PhantomData, } -impl JsValue for PromiseRaw<'_, T> { +impl<'env, T> JsValue<'env> for PromiseRaw<'env, T> { fn value(&self) -> Value { Value { env: self.env, @@ -25,7 +25,7 @@ impl JsValue for PromiseRaw<'_, T> { } } -impl JsObjectValue for PromiseRaw<'_, T> {} +impl<'env, T> JsObjectValue<'env> for PromiseRaw<'env, T> {} impl TypeName for PromiseRaw<'_, T> { fn type_name() -> &'static str { diff --git a/crates/napi/src/env.rs b/crates/napi/src/env.rs index f264c848..edc84b54 100644 --- a/crates/napi/src/env.rs +++ b/crates/napi/src/env.rs @@ -179,7 +179,7 @@ impl Env { unsafe { self.create_string_from_c_char(s.as_ptr().cast(), s.len() as isize) } } - pub fn create_string_from_std(&self, s: String) -> Result { + pub fn create_string_from_std<'env>(&self, s: String) -> Result> { unsafe { self.create_string_from_c_char(s.as_ptr().cast(), s.len() as isize) } } @@ -189,14 +189,14 @@ impl Env { /// # Safety /// /// Create JsString from known valid utf-8 string - pub unsafe fn create_string_from_c_char( + pub unsafe fn create_string_from_c_char<'env>( &self, data_ptr: *const c_char, len: isize, - ) -> Result { + ) -> Result> { let mut raw_value = ptr::null_mut(); check_status!(unsafe { sys::napi_create_string_utf8(self.0, data_ptr, len, &mut raw_value) })?; - Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) }) + unsafe { JsString::from_napi_value(self.0, raw_value) } } pub fn create_string_utf16(&self, chars: &[u16]) -> Result { @@ -204,7 +204,7 @@ impl Env { check_status!(unsafe { sys::napi_create_string_utf16(self.0, chars.as_ptr(), chars.len() as isize, &mut raw_value) })?; - Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) }) + unsafe { JsString::from_napi_value(self.0, raw_value) } } pub fn create_string_latin1(&self, chars: &[u8]) -> Result { @@ -217,7 +217,7 @@ impl Env { &mut raw_value, ) })?; - Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) }) + unsafe { JsString::from_napi_value(self.0, raw_value) } } pub fn create_symbol(&self, description: Option<&str>) -> Result { diff --git a/crates/napi/src/error.rs b/crates/napi/src/error.rs index 506d78d9..ac262db7 100644 --- a/crates/napi/src/error.rs +++ b/crates/napi/src/error.rs @@ -466,16 +466,14 @@ macro_rules! check_status_and_type { format!($msg, format!("Object {}", object)) } ValueType::Boolean | ValueType::Number => { - let value = - unsafe { $crate::Unknown::from_raw_unchecked($env, $val).coerce_to_string()? } - .into_utf8()?; + let val = $crate::Unknown::from_raw_unchecked($env, $val); + let value = val.coerce_to_string()?.into_utf8()?; format!($msg, format!("{} {} ", value_type, value.as_str()?)) } #[cfg(feature = "napi6")] ValueType::BigInt => { - let value = - unsafe { $crate::Unknown::from_raw_unchecked($env, $val).coerce_to_string()? } - .into_utf8()?; + let val = $crate::Unknown::from_raw_unchecked($env, $val); + let value = val.coerce_to_string()?.into_utf8()?; format!($msg, format!("{} {} ", value_type, value.as_str()?)) } _ => format!($msg, value_type), diff --git a/crates/napi/src/js_values/de.rs b/crates/napi/src/js_values/de.rs index c883b841..81479fb8 100644 --- a/crates/napi/src/js_values/de.rs +++ b/crates/napi/src/js_values/de.rs @@ -5,8 +5,7 @@ use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Unexpected, V use crate::bindgen_runtime::BigInt; use crate::{ bindgen_runtime::{BufferSlice, FromNapiValue}, - type_of, Error, JsArrayBuffer, JsObject, JsString, NapiValue, Result, Status, Unknown, Value, - ValueType, + type_of, Error, JsArrayBuffer, JsObject, NapiValue, Result, Status, Unknown, Value, ValueType, }; pub struct De<'env>(pub(crate) &'env Value); @@ -39,10 +38,9 @@ impl<'x> serde::de::Deserializer<'x> for &mut De<'_> { visitor.visit_f64(js_number) } } - ValueType::String => { - let js_string = unsafe { JsString::from_raw_unchecked(self.0.env, self.0.value) }; - visitor.visit_str(js_string.into_utf8()?.as_str()?) - } + ValueType::String => visitor.visit_str( + unsafe { ::from_napi_value(self.0.env, self.0.value) }?.as_str(), + ), ValueType::Object => { let js_object = unsafe { JsObject::from_raw_unchecked(self.0.env, self.0.value) }; if js_object.is_array()? { @@ -169,9 +167,7 @@ impl<'x> serde::de::Deserializer<'x> for &mut De<'_> { let js_value_type = type_of!(self.0.env, self.0.value)?; match js_value_type { ValueType::String => visitor.visit_enum(JsEnumAccess::new( - unsafe { JsString::from_raw_unchecked(self.0.env, self.0.value) } - .into_utf8()? - .into_owned()?, + unsafe { FromNapiValue::from_napi_value(self.0.env, self.0.value) }?, None, )), ValueType::Object => { @@ -187,12 +183,9 @@ impl<'x> serde::de::Deserializer<'x> for &mut De<'_> { ), )) } else { - let key = properties.get_element::(0)?; - let value: Unknown = js_object.get_property(key)?; - visitor.visit_enum(JsEnumAccess::new( - key.into_utf8()?.into_owned()?, - Some(&value.0), - )) + let key = properties.get_element::(0)?; + let value: Unknown = js_object.get_named_property_unchecked(&key)?; + visitor.visit_enum(JsEnumAccess::new(key, Some(&value.0))) } } _ => Err(Error::new( @@ -415,8 +408,8 @@ impl<'de> MapAccess<'de> for JsObjectAccess<'_> { format!("Index:{} out of range: {}", self.property_len, self.idx), )); } - let prop_name = self.properties.get_element::(self.idx)?; - let value: Unknown = self.value.get_property(prop_name)?; + let prop_name = self.properties.get_element::(self.idx)?; + let value: Unknown = self.value.get_named_property_unchecked(&prop_name)?; self.idx += 1; let mut de = De(&value.0); diff --git a/crates/napi/src/js_values/function.rs b/crates/napi/src/js_values/function.rs index 53a9ebbc..b08da751 100644 --- a/crates/napi/src/js_values/function.rs +++ b/crates/napi/src/js_values/function.rs @@ -7,7 +7,7 @@ use crate::{ threadsafe_function::{ThreadsafeCallContext, ThreadsafeFunction}, }; use crate::{ - bindgen_runtime::{ToNapiValue, TypeName, ValidateNapiValue}, + bindgen_runtime::{FromNapiValue, ToNapiValue, TypeName, ValidateNapiValue}, check_pending_exception, sys, Error, JsObject, JsString, NapiRaw, NapiValue, Result, Status, Unknown, ValueType, }; @@ -123,7 +123,7 @@ impl JsFunction { check_pending_exception!(self.0.env, unsafe { sys::napi_get_named_property(self.0.env, self.0.value, c"name".as_ptr().cast(), &mut name) })?; - let name_value = unsafe { JsString::from_raw_unchecked(self.0.env, name) }; + let name_value = unsafe { JsString::from_napi_value(self.0.env, name) }?; Ok(name_value.into_utf8()?.as_str()?.to_owned()) } diff --git a/crates/napi/src/js_values/global.rs b/crates/napi/src/js_values/global.rs index e1d4e665..0155032a 100644 --- a/crates/napi/src/js_values/global.rs +++ b/crates/napi/src/js_values/global.rs @@ -6,26 +6,26 @@ pub struct JsGlobal<'env>( pub(crate) std::marker::PhantomData<&'env ()>, ); -impl JsValue for JsGlobal<'_> { +impl<'env> JsValue<'env> for JsGlobal<'env> { fn value(&self) -> Value { self.0 } } -impl JsObjectValue for JsGlobal<'_> {} +impl<'env> JsObjectValue<'env> for JsGlobal<'env> {} pub struct JsTimeout<'env>( pub(crate) Value, pub(crate) std::marker::PhantomData<&'env ()>, ); -impl JsValue for JsTimeout<'_> { +impl<'env> JsValue<'env> for JsTimeout<'env> { fn value(&self) -> Value { self.0 } } -impl JsObjectValue for JsTimeout<'_> {} +impl<'env> JsObjectValue<'env> for JsTimeout<'env> {} impl FromNapiValue for JsTimeout<'_> { unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { @@ -44,13 +44,13 @@ pub struct JSON<'env>( pub(crate) std::marker::PhantomData<&'env ()>, ); -impl JsValue for JSON<'_> { +impl<'env> JsValue<'env> for JSON<'env> { fn value(&self) -> Value { self.0 } } -impl JsObjectValue for JSON<'_> {} +impl<'env> JsObjectValue<'env> for JSON<'env> {} impl FromNapiValue for JSON<'_> { unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { diff --git a/crates/napi/src/js_values/mod.rs b/crates/napi/src/js_values/mod.rs index 0d2824c5..8627ac49 100644 --- a/crates/napi/src/js_values/mod.rs +++ b/crates/napi/src/js_values/mod.rs @@ -112,7 +112,7 @@ impl TypeName for JsSymbol<'_> { } } -impl JsValue for JsSymbol<'_> { +impl<'env> JsValue<'env> for JsSymbol<'env> { fn value(&self) -> Value { self.0 } @@ -154,11 +154,11 @@ impl TypeName for JsExternal { #[cfg(feature = "compat-mode")] impl ValidateNapiValue for JsExternal {} -pub trait JsValue: Sized { +pub trait JsValue<'env>: Sized { fn value(&self) -> Value; /// Convert the value to an unknown - fn to_unknown(&self) -> Unknown { + fn to_unknown(&self) -> Unknown<'env> { Unknown( Value { env: self.value().env, @@ -201,11 +201,14 @@ pub trait JsValue: Sized { check_status!(unsafe { sys::napi_coerce_to_string(env, self.value().value, &mut new_raw_value) })?; - Ok(JsString(Value { - env, - value: new_raw_value, - value_type: ValueType::String, - })) + Ok(JsString( + Value { + env, + value: new_raw_value, + value_type: ValueType::String, + }, + std::marker::PhantomData, + )) } fn coerce_to_object(self) -> Result { @@ -291,7 +294,7 @@ pub trait JsValue: Sized { } } -pub trait JsObjectValue: JsValue { +pub trait JsObjectValue<'env>: JsValue<'env> { fn set_property(&mut self, key: K, value: V) -> Result<()> where K: NapiRaw, @@ -657,7 +660,7 @@ pub trait JsObjectValue: JsValue { } } -impl NapiRaw for T { +impl<'env, T: JsValue<'env>> NapiRaw for T { unsafe fn raw(&self) -> sys::napi_value { self.value().value } @@ -747,16 +750,19 @@ macro_rules! impl_js_value_methods { )) } - pub fn coerce_to_string(self) -> Result { + pub fn coerce_to_string<'env>(self) -> Result> { let mut new_raw_value = ptr::null_mut(); check_status!(unsafe { sys::napi_coerce_to_string(self.0.env, self.0.value, &mut new_raw_value) })?; - Ok(JsString(Value { - env: self.0.env, - value: new_raw_value, - value_type: ValueType::String, - })) + Ok(JsString( + Value { + env: self.0.env, + value: new_raw_value, + value_type: ValueType::String, + }, + std::marker::PhantomData, + )) } pub fn coerce_to_object(self) -> Result { @@ -1232,7 +1238,6 @@ impl_js_value_methods!(JsBuffer); impl_js_value_methods!(JsArrayBuffer); impl_js_value_methods!(JsTypedArray); impl_js_value_methods!(JsDataView); -impl_js_value_methods!(JsString); impl_js_value_methods!(JsObject); #[cfg(feature = "napi5")] impl_js_value_methods!(JsDate); @@ -1261,7 +1266,6 @@ impl_napi_value_trait!(JsBuffer, Object); impl_napi_value_trait!(JsArrayBuffer, Object); impl_napi_value_trait!(JsTypedArray, Object); impl_napi_value_trait!(JsDataView, Object); -impl_napi_value_trait!(JsString, String); impl_napi_value_trait!(JsObject, Object); #[cfg(feature = "napi5")] impl_napi_value_trait!(JsDate, Object); @@ -1276,7 +1280,7 @@ pub struct Unknown<'env>( pub(crate) std::marker::PhantomData<&'env ()>, ); -impl JsValue for Unknown<'_> { +impl<'env> JsValue<'env> for Unknown<'env> { fn value(&self) -> Value { self.0 } diff --git a/crates/napi/src/js_values/number.rs b/crates/napi/src/js_values/number.rs index 81b446e7..f11d8dd7 100644 --- a/crates/napi/src/js_values/number.rs +++ b/crates/napi/src/js_values/number.rs @@ -23,7 +23,7 @@ impl TypeName for JsNumber<'_> { impl ValidateNapiValue for JsNumber<'_> {} -impl JsValue for JsNumber<'_> { +impl<'env> JsValue<'env> for JsNumber<'env> { fn value(&self) -> Value { self.0 } diff --git a/crates/napi/src/js_values/ser.rs b/crates/napi/src/js_values/ser.rs index 9e293881..939ec166 100644 --- a/crates/napi/src/js_values/ser.rs +++ b/crates/napi/src/js_values/ser.rs @@ -16,7 +16,7 @@ impl<'env> Ser<'env> { } } -impl Serializer for Ser<'_> { +impl<'env> Serializer for Ser<'env> { type Ok = Value; type Error = Error; @@ -24,7 +24,7 @@ impl Serializer for Ser<'_> { type SerializeTuple = SeqSerializer; type SerializeTupleStruct = SeqSerializer; type SerializeTupleVariant = SeqSerializer; - type SerializeMap = MapSerializer; + type SerializeMap = MapSerializer<'env>; type SerializeStruct = StructSerializer; type SerializeStructVariant = StructSerializer; @@ -462,13 +462,13 @@ impl ser::SerializeTupleVariant for SeqSerializer { } } -pub struct MapSerializer { - key: JsString, +pub struct MapSerializer<'env> { + key: JsString<'env>, obj: JsObject, } #[doc(hidden)] -impl ser::SerializeMap for MapSerializer { +impl ser::SerializeMap for MapSerializer<'_> { type Ok = Value; type Error = Error; @@ -477,7 +477,7 @@ impl ser::SerializeMap for MapSerializer { T: ?Sized + Serialize, { let env = Env::from_raw(self.obj.0.env); - self.key = JsString(key.serialize(Ser::new(&env))?); + self.key = JsString(key.serialize(Ser::new(&env))?, std::marker::PhantomData); Ok(()) } @@ -487,11 +487,14 @@ impl ser::SerializeMap for MapSerializer { { let env = Env::from_raw(self.obj.0.env); self.obj.set_property( - JsString(Value { - env: self.key.0.env, - value: self.key.0.value, - value_type: ValueType::String, - }), + JsString( + Value { + env: self.key.0.env, + value: self.key.0.value, + value_type: ValueType::String, + }, + std::marker::PhantomData, + ), Unknown(value.serialize(Ser::new(&env))?, std::marker::PhantomData), )?; Ok(()) @@ -504,7 +507,7 @@ impl ser::SerializeMap for MapSerializer { { let env = Env::from_raw(self.obj.0.env); self.obj.set_property( - JsString(key.serialize(Ser::new(&env))?), + JsString(key.serialize(Ser::new(&env))?, std::marker::PhantomData), Unknown(value.serialize(Ser::new(&env))?, std::marker::PhantomData), )?; Ok(()) diff --git a/crates/napi/src/js_values/string/latin1.rs b/crates/napi/src/js_values/string/latin1.rs index 681544b1..bee7272c 100644 --- a/crates/napi/src/js_values/string/latin1.rs +++ b/crates/napi/src/js_values/string/latin1.rs @@ -5,12 +5,12 @@ use crate::JsString; #[cfg(feature = "latin1")] use crate::Result; -pub struct JsStringLatin1 { - pub(crate) inner: JsString, +pub struct JsStringLatin1<'env> { + pub(crate) inner: JsString<'env>, pub(crate) buf: ManuallyDrop>, } -impl JsStringLatin1 { +impl<'env> JsStringLatin1<'env> { pub fn as_slice(&self) -> &[u8] { &self.buf } @@ -27,7 +27,7 @@ impl JsStringLatin1 { self.as_slice().to_vec() } - pub fn into_value(self) -> JsString { + pub fn into_value(self) -> JsString<'env> { self.inner } @@ -39,7 +39,7 @@ impl JsStringLatin1 { } } -impl From for Vec { +impl From> for Vec { fn from(value: JsStringLatin1) -> Self { value.take() } diff --git a/crates/napi/src/js_values/string/mod.rs b/crates/napi/src/js_values/string/mod.rs index d18db289..e9cc19ff 100644 --- a/crates/napi/src/js_values/string/mod.rs +++ b/crates/napi/src/js_values/string/mod.rs @@ -1,23 +1,26 @@ +use std::marker::PhantomData; use std::mem; use std::ptr; -use crate::bindgen_runtime::TypeName; -use crate::bindgen_runtime::ValidateNapiValue; -use crate::ValueType; -use crate::{check_status, sys, Result, Value}; +use crate::{ + bindgen_runtime::{FromNapiValue, TypeName, ValidateNapiValue}, + check_status, sys, Result, Value, ValueType, +}; pub use latin1::JsStringLatin1; pub use utf16::JsStringUtf16; pub use utf8::JsStringUtf8; +use super::JsValue; + mod latin1; mod utf16; mod utf8; #[derive(Clone, Copy)] -pub struct JsString(pub(crate) Value); +pub struct JsString<'env>(pub(crate) Value, pub(crate) PhantomData<&'env ()>); -impl TypeName for JsString { +impl TypeName for JsString<'_> { fn type_name() -> &'static str { "String" } @@ -27,9 +30,28 @@ impl TypeName for JsString { } } -impl ValidateNapiValue for JsString {} +impl ValidateNapiValue for JsString<'_> {} -impl JsString { +impl<'env> JsValue<'env> for JsString<'env> { + fn value(&self) -> Value { + self.0 + } +} + +impl FromNapiValue for JsString<'_> { + unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { + Ok(JsString( + Value { + env, + value: napi_val, + value_type: ValueType::String, + }, + PhantomData, + )) + } +} + +impl<'env> JsString<'env> { pub fn utf8_len(&self) -> Result { let mut length = 0; check_status!(unsafe { @@ -54,7 +76,7 @@ impl JsString { Ok(length) } - pub fn into_utf8(self) -> Result { + pub fn into_utf8(self) -> Result> { let mut written_char_count = 0; let len = self.utf8_len()? + 1; let mut result = Vec::with_capacity(len); @@ -79,7 +101,7 @@ impl JsString { }) } - pub fn into_utf16(self) -> Result { + pub fn into_utf16(self) -> Result> { let mut written_char_count = 0usize; let len = self.utf16_len()? + 1; let mut result = vec![0; len]; @@ -100,7 +122,7 @@ impl JsString { }) } - pub fn into_latin1(self) -> Result { + pub fn into_latin1(self) -> Result> { let mut written_char_count = 0usize; let len = self.latin1_len()? + 1; let mut result = Vec::with_capacity(len); diff --git a/crates/napi/src/js_values/string/utf16.rs b/crates/napi/src/js_values/string/utf16.rs index 4fc94426..88969bc6 100644 --- a/crates/napi/src/js_values/string/utf16.rs +++ b/crates/napi/src/js_values/string/utf16.rs @@ -3,12 +3,12 @@ use std::ops::Deref; use crate::{Error, JsString, Result, Status}; -pub struct JsStringUtf16 { - pub(crate) inner: JsString, +pub struct JsStringUtf16<'env> { + pub(crate) inner: JsString<'env>, pub(crate) buf: Vec, } -impl JsStringUtf16 { +impl<'env> JsStringUtf16<'env> { pub fn as_str(&self) -> Result { if let Some((_, prefix)) = self.as_slice().split_last() { String::from_utf16(prefix).map_err(|e| Error::new(Status::InvalidArg, format!("{}", e))) @@ -29,12 +29,12 @@ impl JsStringUtf16 { self.buf.is_empty() } - pub fn into_value(self) -> JsString { + pub fn into_value(self) -> JsString<'env> { self.inner } } -impl TryFrom for String { +impl TryFrom> for String { type Error = Error; fn try_from(value: JsStringUtf16) -> Result { @@ -42,7 +42,7 @@ impl TryFrom for String { } } -impl Deref for JsStringUtf16 { +impl Deref for JsStringUtf16<'_> { type Target = [u16]; fn deref(&self) -> &[u16] { @@ -50,13 +50,13 @@ impl Deref for JsStringUtf16 { } } -impl AsRef> for JsStringUtf16 { +impl AsRef> for JsStringUtf16<'_> { fn as_ref(&self) -> &Vec { &self.buf } } -impl From for Vec { +impl From> for Vec { fn from(value: JsStringUtf16) -> Self { value.as_slice().to_vec() } diff --git a/crates/napi/src/js_values/string/utf8.rs b/crates/napi/src/js_values/string/utf8.rs index 1f85cc30..3ba87a17 100644 --- a/crates/napi/src/js_values/string/utf8.rs +++ b/crates/napi/src/js_values/string/utf8.rs @@ -3,12 +3,12 @@ use std::str; use crate::{Error, JsString, Result}; -pub struct JsStringUtf8 { - pub(crate) inner: JsString, +pub struct JsStringUtf8<'env> { + pub(crate) inner: JsString<'env>, pub(crate) buf: Vec, } -impl JsStringUtf8 { +impl<'env> JsStringUtf8<'env> { pub fn as_str(&self) -> Result<&str> { Ok(unsafe { str::from_utf8_unchecked(&self.buf) }) } @@ -33,12 +33,12 @@ impl JsStringUtf8 { self.buf } - pub fn into_value(self) -> JsString { + pub fn into_value(self) -> JsString<'env> { self.inner } } -impl TryFrom for String { +impl TryFrom> for String { type Error = Error; fn try_from(value: JsStringUtf8) -> Result { @@ -46,7 +46,7 @@ impl TryFrom for String { } } -impl From for Vec { +impl From> for Vec { fn from(value: JsStringUtf8) -> Self { value.take() } diff --git a/examples/napi-compat-mode/src/env.rs b/examples/napi-compat-mode/src/env.rs index 611a20b3..9e912fe8 100644 --- a/examples/napi-compat-mode/src/env.rs +++ b/examples/napi-compat-mode/src/env.rs @@ -36,7 +36,7 @@ pub fn cast_unknown(ctx: CallContext) -> Result { } #[contextless_function] -fn get_env_variable(env: Env) -> ContextlessResult { +fn get_env_variable(env: Env) -> ContextlessResult> { env .create_string_from_std(std::env::var("npm_package_name").unwrap()) .map(Some) diff --git a/examples/napi-compat-mode/src/function.rs b/examples/napi-compat-mode/src/function.rs index 29d6f0d9..a6a21ab5 100644 --- a/examples/napi-compat-mode/src/function.rs +++ b/examples/napi-compat-mode/src/function.rs @@ -1,13 +1,13 @@ use napi::{ bindgen_prelude::{FnArgs, Function, Null}, - CallContext, JsError, JsObject, JsString, Result, Unknown, + CallContext, JsError, JsObject, JsString, JsValue, Result, Unknown, }; #[js_function(1)] pub fn call_function(ctx: CallContext) -> Result { let js_func = ctx.get::>>(0)?; - let js_string_hello = ctx.env.create_string("hello".as_ref())?.into_unknown(); - let js_string_world = ctx.env.create_string("world".as_ref())?.into_unknown(); + let js_string_hello = ctx.env.create_string("hello".as_ref())?.to_unknown(); + let js_string_world = ctx.env.create_string("world".as_ref())?.to_unknown(); js_func.call((js_string_hello, js_string_world).into())?;