diff --git a/napi/src/js_values/string.rs b/napi/src/js_values/string.rs index c17843da..1587582b 100644 --- a/napi/src/js_values/string.rs +++ b/napi/src/js_values/string.rs @@ -1,31 +1,24 @@ -use std::convert::{TryFrom, TryInto}; +use std::convert::TryFrom; use std::mem; -use std::os::raw::c_char; use std::ptr; use std::slice; use std::str; use super::Value; use crate::error::check_status; -use crate::{sys, Error, JsNumber, Result, Status}; +use crate::{sys, Error, Result, Status}; #[derive(Clone, Copy, Debug)] pub struct JsString(pub(crate) Value); impl JsString { + #[inline] pub fn len(&self) -> Result { - let mut raw_length = ptr::null_mut(); - unsafe { - let status = sys::napi_get_named_property( - self.0.env, - self.0.value, - "length\0".as_ptr() as *const c_char, - &mut raw_length, - ); - check_status(status)?; - } - let length: JsNumber = JsNumber::from_raw_unchecked(self.0.env, raw_length); - length.try_into() + let mut length = 0; + check_status(unsafe { + sys::napi_get_value_string_utf8(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length) + })?; + Ok(length as usize) } } diff --git a/test_module/__test__/string.spec.js b/test_module/__test__/string.spec.js new file mode 100644 index 00000000..563191bf --- /dev/null +++ b/test_module/__test__/string.spec.js @@ -0,0 +1,8 @@ +const test = require('ava') + +const bindings = require('../index.node') + +test('should be able to concat string', (t) => { + const fixture = 'JavaScript 🌳 你好 napi' + t.snapshot(bindings.concatString(fixture)) +}) diff --git a/test_module/__test__/string.spec.js.md b/test_module/__test__/string.spec.js.md new file mode 100644 index 00000000..7e3709c6 --- /dev/null +++ b/test_module/__test__/string.spec.js.md @@ -0,0 +1,11 @@ +# Snapshot report for `test_module/__test__/string.spec.js` + +The actual snapshot is saved in `string.spec.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## should be able to concat string + +> Snapshot 1 + + 'JavaScript 🌳 你好 napi + Rust 🦀 string!' diff --git a/test_module/__test__/string.spec.js.snap b/test_module/__test__/string.spec.js.snap new file mode 100644 index 00000000..624728bf Binary files /dev/null and b/test_module/__test__/string.spec.js.snap differ diff --git a/test_module/src/lib.rs b/test_module/src/lib.rs index e54fa5cc..9123aa6f 100644 --- a/test_module/src/lib.rs +++ b/test_module/src/lib.rs @@ -20,6 +20,7 @@ mod either; mod external; mod function; mod napi_version; +mod string; mod symbol; mod task; @@ -58,6 +59,7 @@ fn init(module: &mut Module) -> Result<()> { module.create_named_method("eitherNumberString", either_number_string)?; module.create_named_method("dynamicArgumentLength", dynamic_argument_length)?; module.create_named_method("createTestClass", class::create_test_class)?; + module.create_named_method("concatString", string::concat_string)?; #[cfg(napi4)] module.create_named_method("testExecuteTokioReadfile", test_execute_tokio_readfile)?; #[cfg(napi4)] diff --git a/test_module/src/string.rs b/test_module/src/string.rs new file mode 100644 index 00000000..8728146e --- /dev/null +++ b/test_module/src/string.rs @@ -0,0 +1,8 @@ +use napi::{CallContext, JsString, Result}; + +#[js_function(1)] +pub fn concat_string(ctx: CallContext) -> Result { + let in_string = ctx.get::(0)?; + let out_string = format!("{} + Rust 🦀 string!", in_string.as_str()?); + ctx.env.create_string_from_std(out_string) +}