use {
beef::lean::Cow,
std::fmt::{Debug, Display},
widestring::{error::NulError, U16CStr},
};
pub(crate) type ItemType = u16;
#[derive(PartialEq, Eq)]
#[repr(transparent)]
pub struct TStr {
pub(super) inner: U16CStr,
}
impl TStr {
pub const fn from_impl(cstr: &U16CStr) -> &Self {
unsafe { &*(cstr as *const U16CStr as *const Self) }
}
pub const fn as_ptr(&self) -> *const u16 {
self.inner.as_ptr()
}
pub fn from_slice(slice: &[u16]) -> Result<&Self, impl std::error::Error> {
let cstr = U16CStr::from_slice(slice)?;
Ok::<_, NulError<_>>(Self::from_impl(cstr))
}
pub unsafe fn from_ptr<'a>(ptr: *const u16) -> &'a Self {
let cstr = unsafe { U16CStr::from_ptr_str(ptr) };
Self::from_impl(cstr)
}
pub unsafe fn from_ptr_optional<'a>(ptr: *const u16) -> Option<&'a Self> {
(!ptr.is_null()).then(|| unsafe { Self::from_ptr(ptr) })
}
pub fn to_str(&self) -> Cow<str> {
self.inner.to_string_lossy().into()
}
pub const fn len(&self) -> usize {
self.inner.len()
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
self.inner.chars_lossy()
}
}
impl Debug for TStr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&self.inner.display(), f)
}
}
impl Display for TStr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.inner.display(), f)
}
}