Skip to main content

realhydroper_utf16/
utf16string.rs

1use crate::{utils::*, Utf16Str, Utf16String};
2use std::ops::{Deref, DerefMut};
3
4impl Deref for Utf16String {
5    type Target = Utf16Str;
6
7    #[inline]
8    fn deref(&self) -> &Self::Target {
9        unsafe { Utf16Str::from_utf16_unchecked(self.buf.as_slice()) }
10    }
11}
12
13impl DerefMut for Utf16String {
14    fn deref_mut(&mut self) -> &mut Self::Target {
15        unsafe { Utf16Str::from_utf16_unchecked_mut(self.buf.as_mut_slice()) }
16    }
17}
18
19impl<T: AsRef<str>> From<T> for Utf16String {
20    fn from(value: T) -> Self {
21        let mut r = Utf16String::new();
22        r.push_utf8_str(value.as_ref());
23        r
24    }
25}
26
27impl From<Utf16String> for String {
28    fn from(value: Utf16String) -> Self {
29        value.to_utf8()
30    }
31}
32
33impl Utf16String {
34    pub fn new() -> Self {
35        Utf16String {
36            buf: vec![],
37        }
38    }
39
40    #[inline]
41    pub fn as_mut_utf16_str(&mut self) -> &mut Utf16Str {
42        self
43    }
44
45    #[inline]
46    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u16> {
47        &mut self.buf
48    }
49
50    #[inline]
51    pub fn clear(&mut self) {
52        self.buf.clear();
53    }
54
55    pub fn insert(&mut self, mut index: usize, ch: char) {
56        for cu in encode_char(ch) {
57            self.buf.insert(index, cu);
58            index += 1;
59        }
60    }
61
62    pub fn insert_utf16_str(&mut self, mut index: usize, string: &Utf16Str) {
63        for cu in string.raw.iter() {
64            self.buf.insert(index, *cu);
65            index += 1;
66        }
67    }
68
69    pub fn insert_utf8_str(&mut self, mut index: usize, string: &str) {
70        for ch in string.chars() {
71            for cu in encode_char(ch) {
72                self.buf.insert(index, cu);
73                index += 1;
74            }
75        }
76    }
77
78    #[inline]
79    pub fn push(&mut self, ch: char) {
80        self.buf.extend(encode_char(ch));
81    }
82
83    pub fn push_utf16_str(&mut self, string: &Utf16Str) {
84        self.buf.extend(&string.raw);
85    }
86
87    pub fn push_utf8_str(&mut self, string: &str) {
88        for ch in string.chars() {
89            self.buf.extend(encode_char(ch));
90        }
91    }
92
93    /// Removes a surrogate pair or a code unit from the specified
94    /// index in code units, and returns the code point that was
95    /// removed.
96    /// 
97    /// # Panics
98    /// 
99    /// Panics if the index is out of bounds.
100    pub fn remove(&mut self, index: usize) -> char {
101        assert!(index < self.len(), "removing character out of bounsd");
102        let cu1 = self.buf[index];
103        if is_high_surrogate(cu1) && (index + 1) < self.len() {
104            let cu2 = self.buf[index + 1];
105            if is_low_surrogate(cu2) {
106                self.buf.remove(index);
107                self.buf.remove(index);
108                return decode_char(cu1, cu2);
109            }
110        }
111        self.buf.remove(index);
112        unsafe { char::from_u32_unchecked(cu1 as u32) }
113    }
114
115    /// Removes the last surrogate pair or code unit, and returns the code point that was
116    /// removed.
117    pub fn pop(&mut self) -> Option<char> {
118        let l = self.len();
119        if l == 0 {
120            return None;
121        }
122        let i = l - 1;
123        let cu2 = self.buf[i];
124        if is_low_surrogate(cu2) && l > 1 {
125            let cu1 = self.buf[i - 1];
126            if is_high_surrogate(cu1) {
127                let i2 = i - 1;
128                self.buf.remove(i2);
129                self.buf.remove(i2);
130                return Some(decode_char(cu1, cu2));
131            }
132        }
133        self.buf.remove(i);
134        Some(unsafe { char::from_u32_unchecked(cu2 as u32) })
135    }
136}
137
138impl Default for Utf16String {
139    fn default() -> Self {
140        Utf16String::new()
141    }
142}