napi_h/js_values/string/
mod.rs

1use std::mem;
2use std::ptr;
3
4use crate::bindgen_runtime::TypeName;
5use crate::bindgen_runtime::ValidateNapiValue;
6use crate::ValueType;
7use crate::{check_status, sys, Result, Value};
8
9pub use latin1::JsStringLatin1;
10pub use utf16::JsStringUtf16;
11pub use utf8::JsStringUtf8;
12
13mod latin1;
14mod utf16;
15mod utf8;
16
17#[derive(Clone, Copy)]
18pub struct JsString(pub(crate) Value);
19
20impl TypeName for JsString {
21  fn type_name() -> &'static str {
22    "String"
23  }
24
25  fn value_type() -> crate::ValueType {
26    ValueType::String
27  }
28}
29
30impl ValidateNapiValue for JsString {}
31
32impl JsString {
33  pub fn utf8_len(&self) -> Result<usize> {
34    let mut length = 0;
35    check_status!(unsafe {
36      sys::napi_get_value_string_utf8(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length)
37    })?;
38    Ok(length)
39  }
40
41  pub fn utf16_len(&self) -> Result<usize> {
42    let mut length = 0;
43    check_status!(unsafe {
44      sys::napi_get_value_string_utf16(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length)
45    })?;
46    Ok(length)
47  }
48
49  pub fn latin1_len(&self) -> Result<usize> {
50    let mut length = 0;
51    check_status!(unsafe {
52      sys::napi_get_value_string_latin1(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length)
53    })?;
54    Ok(length)
55  }
56
57  pub fn into_utf8(self) -> Result<JsStringUtf8> {
58    let mut written_char_count = 0;
59    let len = self.utf8_len()? + 1;
60    let mut result = Vec::with_capacity(len);
61    let buf_ptr = result.as_mut_ptr();
62    check_status!(unsafe {
63      sys::napi_get_value_string_utf8(
64        self.0.env,
65        self.0.value,
66        buf_ptr,
67        len,
68        &mut written_char_count,
69      )
70    })?;
71
72    Ok(JsStringUtf8 {
73      inner: self,
74      buf: result,
75    })
76  }
77
78  pub fn into_utf16(self) -> Result<JsStringUtf16> {
79    let mut written_char_count = 0usize;
80    let len = self.utf16_len()? + 1;
81    let mut result = vec![0; len];
82    let buf_ptr = result.as_mut_ptr();
83    check_status!(unsafe {
84      sys::napi_get_value_string_utf16(
85        self.0.env,
86        self.0.value,
87        buf_ptr,
88        len,
89        &mut written_char_count,
90      )
91    })?;
92
93    Ok(JsStringUtf16 {
94      inner: self,
95      buf: result,
96    })
97  }
98
99  pub fn into_latin1(self) -> Result<JsStringLatin1> {
100    let mut written_char_count = 0usize;
101    let len = self.latin1_len()? + 1;
102    let mut result = Vec::with_capacity(len);
103    let buf_ptr = result.as_mut_ptr();
104    check_status!(unsafe {
105      sys::napi_get_value_string_latin1(
106        self.0.env,
107        self.0.value,
108        buf_ptr,
109        len,
110        &mut written_char_count,
111      )
112    })?;
113
114    mem::forget(result);
115
116    Ok(JsStringLatin1 {
117      inner: self,
118      buf: mem::ManuallyDrop::new(unsafe {
119        Vec::from_raw_parts(buf_ptr as *mut _, written_char_count, written_char_count)
120      }),
121    })
122  }
123}