use std::{os::raw::c_char, slice, sync::Arc};
use crate::{error::CreationError, Library};
pub(crate) struct UlString {
lib: Arc<Library>,
internal: ul_sys::ULString,
}
impl UlString {
pub(crate) unsafe fn from_str(lib: Arc<Library>, s: &str) -> Result<Self, CreationError> {
let internal = Self::from_str_unmanaged(&lib, s)?;
Ok(Self { lib, internal })
}
pub(crate) unsafe fn from_str_unmanaged(
lib: &Arc<Library>,
s: &str,
) -> Result<ul_sys::ULString, CreationError> {
let internal = lib
.ultralight()
.ulCreateStringUTF8(s.as_bytes().as_ptr() as *const c_char, s.len());
if internal.is_null() {
Err(CreationError::UlStringCreationError(s.to_string()))
} else {
Ok(internal)
}
}
pub(crate) unsafe fn to_ul(&self) -> ul_sys::ULString {
self.internal
}
pub(crate) unsafe fn copy_raw_to_string(
lib: &Arc<Library>,
raw: ul_sys::ULString,
) -> Result<String, CreationError> {
if raw.is_null() {
return Err(CreationError::NullReference);
}
let raw_data = lib.ultralight().ulStringGetData(raw);
if raw_data.is_null() {
return Err(CreationError::NullReference);
}
let utf8_data = slice::from_raw_parts(raw_data, lib.ultralight().ulStringGetLength(raw))
.iter()
.map(|c| *c as u8)
.collect();
String::from_utf8(utf8_data).map_err(|e| e.into())
}
}
impl Drop for UlString {
fn drop(&mut self) {
unsafe {
self.lib.ultralight().ulDestroyString(self.internal);
}
}
}