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}
124