#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::{string::String, vec::Vec};
#[cfg(feature = "std")]
use std::{string::String, vec::Vec};
use core::slice;
#[repr(C)]
#[derive(Debug)]
pub struct UnicodeString {
pub length: u16, pub maximum_length: u16, pub buffer: *mut u16, }
impl UnicodeString {
pub fn is_empty(&self) -> bool {
self.length == 0 || self.buffer.is_null()
}
pub unsafe fn as_slice(&self) -> &[u16] {
if self.is_empty() {
return &[];
}
let char_count = (self.length / 2) as usize;
unsafe { slice::from_raw_parts(self.buffer, char_count) }
}
pub unsafe fn to_string(&self) -> String {
let slice = unsafe { self.as_slice() };
String::from_utf16_lossy(slice)
}
pub unsafe fn to_string_lowercase(&self) -> String {
unsafe { self.to_string() }.to_lowercase()
}
pub unsafe fn eq_ignore_case(&self, other: &str) -> bool {
let self_str = unsafe { self.to_string_lowercase() };
self_str == other.to_lowercase()
}
pub unsafe fn eq_wide_ignore_case(&self, other: &[u16]) -> bool {
let slice = unsafe { self.as_slice() };
if slice.len() != other.len() {
return false;
}
slice.iter().zip(other.iter()).all(|(&a, &b)| {
let a_lower = if a >= 'A' as u16 && a <= 'Z' as u16 {
a + 32
} else {
a
};
let b_lower = if b >= 'A' as u16 && b <= 'Z' as u16 {
b + 32
} else {
b
};
a_lower == b_lower
})
}
}
pub fn str_to_wide(s: &str) -> Vec<u16> {
s.encode_utf16().collect()
}