static_collections/ffi/
wstring.rs1use core::{fmt, mem::MaybeUninit, ops::{Index, IndexMut}, slice::SliceIndex};
4
5use crate::vec::StaticVec;
6
7#[derive(Default, Debug, Clone)]
9pub struct StaticWString<const N:usize>
10{
11 internal:StaticVec<N,u16>
12}
13
14impl<const N:usize> StaticWString<N>
15{
16 pub const fn new()->Self
21 {
22 Self
23 {
24 internal:StaticVec::new()
25 }
26 }
27
28
29 pub const fn len(&self)->usize
42 {
43 self.internal.len()
44 }
45
46 pub const fn capacity(&self)->usize
55 {
56 N
57 }
58
59 pub const fn is_empty(&self)->bool
71 {
72 self.len()==0
73 }
74
75 pub const fn as_slice(&self)->&[u16]
85 {
86 self.internal.as_slice()
87 }
88
89
90 pub const fn as_mut_slice(&mut self)->&mut [u16]
105 {
106 self.internal.as_mut_slice()
107 }
108
109 pub const fn as_ptr(&self)->*const u16
111 {
112 self.internal.as_ptr()
113 }
114
115 pub const fn as_mut_ptr(&mut self)->*mut u16
117 {
118 self.internal.as_mut_ptr()
119 }
120
121 pub fn push_char(&mut self,ch:char)
132 {
133 let rsvd_size=ch.len_utf16();
134 if self.capacity()-self.len()>rsvd_size
135 {
136 unsafe
137 {
138 let mut x:MaybeUninit<[u16;2]>=MaybeUninit::uninit();
139 let u=ch.encode_utf16(x.assume_init_mut());
140 for c in u
141 {
142 self.internal.push(*c);
143 }
144 }
145 }
146 }
147
148 pub fn push_str(&mut self,s:&str)
159 {
160 for c in s.encode_utf16()
161 {
162 self.internal.push(c)
163 }
164 }
165
166 pub fn insert_char(&mut self,index:usize,ch:char)
177 {
178 let mut x:MaybeUninit<[u16;2]>=MaybeUninit::uninit();
179 let rsvd_size=ch.len_utf16();
180 if self.capacity()-self.len()>rsvd_size
181 {
182 let copy_range=index..self.len();
183 let u=unsafe
184 {
185 self.internal.force_resize(self.len()+rsvd_size);
186 ch.encode_utf16(x.assume_init_mut())
187 };
188 self.internal.copy_within(copy_range,index+rsvd_size);
189 for (i,c) in u.iter().enumerate()
190 {
191 self[index+i]= *c;
192 }
193 }
194 }
195 pub fn insert_str(&mut self,index:usize,s:&str)
206 {
207 let insert_len:usize=s.encode_utf16().count();
210 let copy_range=index..self.len();
211 unsafe
213 {
214 self.internal.force_resize(self.len()+insert_len);
215 }
216 self.internal.copy_within(copy_range,index+insert_len);
217 for (i,c) in s.encode_utf16().enumerate()
218 {
219 self[index+i]=c;
220 }
221 }
222}
223
224impl<I:SliceIndex<[u16]>,const N:usize> Index<I> for StaticWString<N>
225{
226 type Output = I::Output;
227
228 fn index(&self, index: I) -> &Self::Output
229 {
230 &self.internal[index]
231 }
232}
233
234impl<I:SliceIndex<[u16]>,const N:usize> IndexMut<I> for StaticWString<N>
235{
236 fn index_mut(&mut self, index: I) -> &mut Self::Output
237 {
238 &mut self.internal[index]
239 }
240}
241
242impl<const N:usize> From<&str> for StaticWString<N>
243{
244 fn from(value: &str) -> Self
245 {
246 let mut s=Self::new();
247 s.push_str(value);
248 s
249 }
250}
251
252impl<const N:usize> PartialEq<[u16]> for StaticWString<N>
253{
254 fn eq(&self, other: &[u16]) -> bool
255 {
256 self.as_slice()==other
257 }
258}
259
260impl<const M:usize,const N:usize> PartialEq<[u16;M]> for StaticWString<N>
261{
262 fn eq(&self, other: &[u16;M]) -> bool
263 {
264 self.as_slice()==other
265 }
266}
267
268impl<const N:usize> PartialOrd<[u16]> for StaticWString<N>
269{
270 fn partial_cmp(&self, other: &[u16]) -> Option<core::cmp::Ordering>
271 {
272 self.as_slice().partial_cmp(other)
273 }
274}
275
276impl<const M:usize,const N:usize> PartialOrd<[u16;M]> for StaticWString<N>
277{
278 fn partial_cmp(&self, other: &[u16;M]) -> Option<core::cmp::Ordering>
279 {
280 self.as_slice().partial_cmp(other)
281 }
282}
283
284impl<const N:usize> fmt::Display for StaticWString<N>
285{
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
287 {
288 use fmt::Write;
289 for c in char::decode_utf16(self.iter())
290 {
291 match c
292 {
293 Ok(c)=>f.write_char(c),
294 Err(_)=>f.write_char(char::REPLACEMENT_CHARACTER)
295 }?;
296 }
297 Ok(())
298 }
299}
300
301impl<const N:usize> fmt::Write for StaticWString<N>
302{
303 fn write_char(&mut self, c: char) -> fmt::Result
304 {
305 self.push_char(c);
306 Ok(())
307 }
308
309 fn write_str(&mut self, s: &str) -> fmt::Result
310 {
311 self.push_str(s);
312 Ok(())
313 }
314}
315
316impl<'a,const N:usize> StaticWString<N>
317{
318 fn iter(&'a self)->StaticWIter<'a,N>
320 {
321 StaticWIter
322 {
323 internal:StaticWIterator
324 {
325 index:0,
326 source:self
327 }
328 }
329 }
330}
331
332struct StaticWIterator<'a,const N:usize>
333{
334 index:usize,
335 source:&'a StaticWString<N>
336}
337
338impl<'a,const N:usize> Iterator for StaticWIterator<'a,N>
339{
340 type Item = u16;
341
342 fn next(&mut self) -> Option<Self::Item>
343 {
344 let i=self.index;
345 if i<self.source.len()
346 {
347 self.index+=1;
348 Some(self.source[i])
349 }
350 else
351 {
352 None
353 }
354 }
355}
356
357struct StaticWIter<'a,const N:usize>
358{
359 internal:StaticWIterator<'a,N>
360}
361
362impl<'a,const N:usize> IntoIterator for StaticWIter<'a,N>
363{
364 type IntoIter = StaticWIterator<'a,N>;
365 type Item = u16;
366
367 fn into_iter(self) -> Self::IntoIter
368 {
369 self.internal
370 }
371}
372
373#[cfg(test)]
374mod test
375{
376 extern crate std;
377 use std::format;
378 use super::StaticWString;
379
380 #[test] fn correct_fmt()
381 {
382 let s:StaticWString<32>=StaticWString::from("abcd魑魅魍魉1234😀🤣😅👍");
383 let ss=format!("This is {s}!");
384 assert_eq!(ss,"This is abcd魑魅魍魉1234😀🤣😅👍!");
385 }
386}