use node_api_system::napi_status; use crate::{ sys::{napi_create_string_utf8, napi_get_value_string_utf8}, Env, Error, Result, Value, }; use std::{mem::MaybeUninit, os::raw::c_char}; #[derive(Clone, Copy)] pub struct String<'a>(pub Value<'a>); impl<'a> String<'a> { pub(crate) fn from_value(value: Value) -> String { String(value) } pub fn value(&self) -> Value<'a> { self.0 } pub fn env(&self) -> Env<'a> { self.0.env() } pub fn new(env: Env<'a>, value: &str) -> Result> { let value = unsafe { let mut result = MaybeUninit::uninit(); let status = napi_create_string_utf8( env.raw(), value.as_ptr() as *const c_char, value.len(), result.as_mut_ptr(), ); if status != napi_status::napi_ok { return Err(Error::from_last_node_api_error(env.raw(), status)); } result.assume_init() }; let value = Value::from_raw(env, value); let value = String(value); Ok(value) } pub fn get(&self) -> Result { let len = unsafe { let mut result = MaybeUninit::uninit(); let status = napi_get_value_string_utf8( self.env().raw(), self.value().raw(), std::ptr::null_mut(), 0, result.as_mut_ptr(), ); if status != napi_status::napi_ok { return Err(Error::from_last_node_api_error(self.env().raw(), status)); } result.assume_init() }; let mut bytes: Vec = Vec::with_capacity(len + 1); let len = unsafe { let mut result = MaybeUninit::uninit(); let status = napi_get_value_string_utf8( self.env().raw(), self.value().raw(), bytes.as_mut_ptr() as *mut c_char, bytes.capacity(), result.as_mut_ptr(), ); if status != napi_status::napi_ok { return Err(Error::from_last_node_api_error(self.env().raw(), status)); } result.assume_init() }; unsafe { bytes.set_len(len) }; let string = unsafe { std::string::String::from_utf8_unchecked(bytes) }; Ok(string) } }