mirror of
https://github.com/napi-rs/napi-rs.git
synced 2025-12-08 19:56:07 +00:00
refactor!(napi): add lifetime to JsString (#2614)
This commit is contained in:
parent
c808386a8f
commit
65fe29c854
@ -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<JsString> {
|
||||
pub fn create_array_json(_: Env) -> ContextlessResult<String> {
|
||||
let a: Vec<u32> = vec![42; 1000];
|
||||
let arr_string = to_string(&a)?;
|
||||
env.create_string(arr_string.as_str()).map(Some)
|
||||
Ok(Some(arr_string))
|
||||
}
|
||||
|
||||
#[contextless_function]
|
||||
|
||||
@ -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() ),+
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ pub struct PromiseRaw<'env, T> {
|
||||
_phantom: &'env PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> 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<T> JsValue for PromiseRaw<'_, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> JsObjectValue for PromiseRaw<'_, T> {}
|
||||
impl<'env, T> JsObjectValue<'env> for PromiseRaw<'env, T> {}
|
||||
|
||||
impl<T: FromNapiValue> TypeName for PromiseRaw<'_, T> {
|
||||
fn type_name() -> &'static str {
|
||||
|
||||
@ -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<JsString> {
|
||||
pub fn create_string_from_std<'env>(&self, s: String) -> Result<JsString<'env>> {
|
||||
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<JsString> {
|
||||
) -> Result<JsString<'env>> {
|
||||
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<JsString> {
|
||||
@ -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<JsString> {
|
||||
@ -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<JsSymbol> {
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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 { <String as FromNapiValue>::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::<JsString>(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::<String>(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::<JsString>(self.idx)?;
|
||||
let value: Unknown = self.value.get_property(prop_name)?;
|
||||
let prop_name = self.properties.get_element::<String>(self.idx)?;
|
||||
let value: Unknown = self.value.get_named_property_unchecked(&prop_name)?;
|
||||
|
||||
self.idx += 1;
|
||||
let mut de = De(&value.0);
|
||||
|
||||
@ -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())
|
||||
}
|
||||
|
||||
|
||||
@ -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<Self> {
|
||||
@ -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<Self> {
|
||||
|
||||
@ -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<JsObject> {
|
||||
@ -291,7 +294,7 @@ pub trait JsValue: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait JsObjectValue: JsValue {
|
||||
pub trait JsObjectValue<'env>: JsValue<'env> {
|
||||
fn set_property<K, V>(&mut self, key: K, value: V) -> Result<()>
|
||||
where
|
||||
K: NapiRaw,
|
||||
@ -657,7 +660,7 @@ pub trait JsObjectValue: JsValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JsValue> 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<JsString> {
|
||||
pub fn coerce_to_string<'env>(self) -> Result<JsString<'env>> {
|
||||
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<JsObject> {
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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(())
|
||||
|
||||
@ -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<Vec<u8>>,
|
||||
}
|
||||
|
||||
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<JsStringLatin1> for Vec<u8> {
|
||||
impl From<JsStringLatin1<'_>> for Vec<u8> {
|
||||
fn from(value: JsStringLatin1) -> Self {
|
||||
value.take()
|
||||
}
|
||||
|
||||
@ -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<Self> {
|
||||
Ok(JsString(
|
||||
Value {
|
||||
env,
|
||||
value: napi_val,
|
||||
value_type: ValueType::String,
|
||||
},
|
||||
PhantomData,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'env> JsString<'env> {
|
||||
pub fn utf8_len(&self) -> Result<usize> {
|
||||
let mut length = 0;
|
||||
check_status!(unsafe {
|
||||
@ -54,7 +76,7 @@ impl JsString {
|
||||
Ok(length)
|
||||
}
|
||||
|
||||
pub fn into_utf8(self) -> Result<JsStringUtf8> {
|
||||
pub fn into_utf8(self) -> Result<JsStringUtf8<'env>> {
|
||||
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<JsStringUtf16> {
|
||||
pub fn into_utf16(self) -> Result<JsStringUtf16<'env>> {
|
||||
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<JsStringLatin1> {
|
||||
pub fn into_latin1(self) -> Result<JsStringLatin1<'env>> {
|
||||
let mut written_char_count = 0usize;
|
||||
let len = self.latin1_len()? + 1;
|
||||
let mut result = Vec::with_capacity(len);
|
||||
|
||||
@ -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<u16>,
|
||||
}
|
||||
|
||||
impl JsStringUtf16 {
|
||||
impl<'env> JsStringUtf16<'env> {
|
||||
pub fn as_str(&self) -> Result<String> {
|
||||
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<JsStringUtf16> for String {
|
||||
impl TryFrom<JsStringUtf16<'_>> for String {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: JsStringUtf16) -> Result<String> {
|
||||
@ -42,7 +42,7 @@ impl TryFrom<JsStringUtf16> 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<Vec<u16>> for JsStringUtf16 {
|
||||
impl AsRef<Vec<u16>> for JsStringUtf16<'_> {
|
||||
fn as_ref(&self) -> &Vec<u16> {
|
||||
&self.buf
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JsStringUtf16> for Vec<u16> {
|
||||
impl From<JsStringUtf16<'_>> for Vec<u16> {
|
||||
fn from(value: JsStringUtf16) -> Self {
|
||||
value.as_slice().to_vec()
|
||||
}
|
||||
|
||||
@ -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<u8>,
|
||||
}
|
||||
|
||||
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<JsStringUtf8> for String {
|
||||
impl TryFrom<JsStringUtf8<'_>> for String {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: JsStringUtf8) -> Result<String> {
|
||||
@ -46,7 +46,7 @@ impl TryFrom<JsStringUtf8> for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JsStringUtf8> for Vec<u8> {
|
||||
impl From<JsStringUtf8<'_>> for Vec<u8> {
|
||||
fn from(value: JsStringUtf8) -> Self {
|
||||
value.take()
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ pub fn cast_unknown(ctx: CallContext) -> Result<JsObject> {
|
||||
}
|
||||
|
||||
#[contextless_function]
|
||||
fn get_env_variable(env: Env) -> ContextlessResult<JsString> {
|
||||
fn get_env_variable(env: Env) -> ContextlessResult<JsString<'static>> {
|
||||
env
|
||||
.create_string_from_std(std::env::var("npm_package_name").unwrap())
|
||||
.map(Some)
|
||||
|
||||
@ -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<Null> {
|
||||
let js_func = ctx.get::<Function<FnArgs<(Unknown, Unknown)>>>(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())?;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user