wraith/structures/
unicode_string.rs1#[cfg(all(not(feature = "std"), feature = "alloc"))]
4use alloc::{string::String, vec::Vec};
5
6#[cfg(feature = "std")]
7use std::{string::String, vec::Vec};
8
9use core::slice;
10
11#[repr(C)]
13#[derive(Debug)]
14pub struct UnicodeString {
15 pub length: u16, pub maximum_length: u16, pub buffer: *mut u16, }
19
20impl UnicodeString {
21 pub fn is_empty(&self) -> bool {
23 self.length == 0 || self.buffer.is_null()
24 }
25
26 pub unsafe fn as_slice(&self) -> &[u16] {
31 if self.is_empty() {
32 return &[];
33 }
34 let char_count = (self.length / 2) as usize;
35 unsafe { slice::from_raw_parts(self.buffer, char_count) }
37 }
38
39 pub unsafe fn to_string(&self) -> String {
44 let slice = unsafe { self.as_slice() };
45 String::from_utf16_lossy(slice)
46 }
47
48 pub unsafe fn to_string_lowercase(&self) -> String {
53 unsafe { self.to_string() }.to_lowercase()
54 }
55
56 pub unsafe fn eq_ignore_case(&self, other: &str) -> bool {
61 let self_str = unsafe { self.to_string_lowercase() };
62 self_str == other.to_lowercase()
63 }
64
65 pub unsafe fn eq_wide_ignore_case(&self, other: &[u16]) -> bool {
70 let slice = unsafe { self.as_slice() };
71 if slice.len() != other.len() {
72 return false;
73 }
74 slice.iter().zip(other.iter()).all(|(&a, &b)| {
75 let a_lower = if a >= 'A' as u16 && a <= 'Z' as u16 {
77 a + 32
78 } else {
79 a
80 };
81 let b_lower = if b >= 'A' as u16 && b <= 'Z' as u16 {
82 b + 32
83 } else {
84 b
85 };
86 a_lower == b_lower
87 })
88 }
89}
90
91pub fn str_to_wide(s: &str) -> Vec<u16> {
93 s.encode_utf16().collect()
94}