1#![allow(unused_variables)]
2#![allow(non_snake_case)]
3#![allow(non_camel_case_types)]
4#![allow(unused_parens)]
5#![allow(unused_assignments)]
6#![allow(unused_mut)]
7#![allow(unused_imports)]
8#![allow(dead_code)]
9use crate::shared_structs::Strunion;
12use crate::shared_structs::Strunion::*;
13use crate::tstr;
14use crate::zstr;
15
16#[cfg(feature = "std")]
17use crate::fstr;
18
19use crate::{str12, str128, str16, str192, str24, str256, str32, str4, str48, str64, str8, str96};
20use core::cmp::{min, Ordering};
21use core::ops::Add;
22
23extern crate alloc;
26use alloc::rc::Rc;
27use alloc::string::String;
28use core::cell::RefCell;
29
30#[derive(Eq, Clone)]
55pub struct Sharedstr<const N: usize = 32> {
56 inner: Rc<RefCell<Strunion<N>>>,
57}
58impl<const N: usize> Sharedstr<N> {
59 pub fn make(s: &str) -> Self {
61 if s.len() < N && N <= 256 {
62 Sharedstr {
63 inner: Rc::new(RefCell::new(fixed(tstr::<N>::from(s)))),
64 }
65 } else {
66 Sharedstr {
67 inner: Rc::new(RefCell::new(owned(String::from(s)))),
68 }
69 }
70 } pub fn from_string(s: String) -> Self {
75 if s.len() < N && N <= 256 {
76 Sharedstr {
77 inner: Rc::new(RefCell::new(fixed(tstr::<N>::from(&s[..])))),
78 }
79 } else {
80 Sharedstr {
81 inner: Rc::new(RefCell::new(owned(s))),
82 }
83 }
84 }
85
86 pub fn from_tstr(s: tstr<N>) -> Self {
88 Sharedstr {
89 inner: Rc::new(RefCell::new(fixed(s))),
90 }
91 }
92
93 pub fn len(&self) -> usize {
103 match &*self.inner.borrow() {
104 fixed(s) => s.len(),
105 owned(s) => s.len(),
106 } } pub fn as_str(&self) -> &str {
111 unsafe {
112 match self.inner.as_ptr().as_ref().unwrap() {
113 fixed(s) => s.as_str(),
114 owned(s) => s.as_str(),
115 } } }
118
119 pub fn as_str_utf8(&self) -> Result<&str, core::str::Utf8Error> {
121 unsafe {
122 match self.inner.as_ptr().as_ref().unwrap() {
123 fixed(s) => s.as_str_safe(),
124 owned(s) => Ok(s.as_str()),
125 } } }
128
129 pub fn new() -> Self {
131 Self::default()
132 }
133
134 pub fn charlen(&self) -> usize {
137 match &*self.inner.borrow() {
138 fixed(s) => s.charlen(),
139 owned(s) => s.chars().count(),
140 } } pub fn to_str(&self) -> &str {
145 self.as_str()
146 } pub fn get_str(&self) -> Option<tstr<N>> {
158 if let fixed(s) = &*self.inner.borrow() {
159 Some(*s)
160 } else {
161 None
162 }
163 } pub fn take_string(&mut self) -> Option<String> {
168 if let (ss @ owned(_)) = &mut *self.inner.borrow_mut() {
169 let mut temp = fixed(tstr::new());
170
171 core::mem::swap(ss, &mut temp);
172 if let owned(t) = temp {
173 Some(t)
174 } else {
175 None
176 }
177 } else {
178 None
179 }
180 } pub fn to_string(self) -> String {
184 match &*self.inner.borrow() {
185 fixed(s) => s.to_string(),
186 owned(s) => s.clone(),
187 } } pub fn nth(&self, n: usize) -> Option<char> {
192 self.to_str().chars().nth(n)
193 }
194
195 pub fn nth_bytechar(&self, n: usize) -> char {
199 match &*self.inner.borrow() {
200 fixed(s) => s.nth_ascii(n),
201 owned(s) => s.as_bytes()[n] as char,
202 }
203 } pub fn nth_ascii(&self, n: usize) -> char {
207 self.nth_bytechar(n)
208 }
209
210 pub fn as_bytes(&self) -> &[u8] {
214 self.as_str().as_bytes()
215 } pub fn set(&mut self, i: usize, c: char) -> bool {
222 match &mut *self.inner.borrow_mut() {
223 fixed(s) => s.set(i, c),
224 owned(s) => unsafe {
225 let ref mut cbuf = [0u8; 4];
226 c.encode_utf8(cbuf);
227 let clen = c.len_utf8();
228 if let Some((bi, rc)) = s.char_indices().nth(i) {
229 if clen == rc.len_utf8() {
230 s.as_bytes_mut()[bi..bi + clen].copy_from_slice(&cbuf[..clen]);
231 return true;
234 }
235 }
236 return false;
237 },
238 } } pub fn is_fixed(&self) -> bool {
243 match &*self.inner.borrow() {
244 fixed(_) => true,
245 owned(_) => false,
246 }
247 } pub fn is_owned(&self) -> bool {
251 !self.is_fixed()
252 }
253
254 pub fn if_fixed<F>(&mut self, f: F)
257 where
258 F: FnOnce(&mut tstr<N>),
259 {
260 if let fixed(s) = &mut *self.inner.borrow_mut() {
261 f(s);
262 }
263 }
264
265 pub fn if_owned<F>(&mut self, f: F)
268 where
269 F: FnOnce(&mut str),
270 {
271 if let owned(s) = &mut *self.inner.borrow_mut() {
272 f(s);
273 }
274 }
275
276 pub fn map_or<F, G, U>(&self, f: F, g: G) -> U
279 where
280 F: FnOnce(&tstr<N>) -> U,
281 G: FnOnce(&str) -> U,
282 {
283 match &*self.inner.borrow() {
284 fixed(s) => f(s),
285 owned(s) => g(&s[..]),
286 } } pub fn map_or_mut<F, G, U>(&mut self, f: &mut F, g: &mut G) -> U
291 where
292 F: FnMut(&mut tstr<N>) -> U,
293 G: FnMut(&mut str) -> U,
294 {
295 match &mut *self.inner.borrow_mut() {
296 fixed(s) => f(s),
297 owned(s) => g(&mut s[..]),
298 } } pub fn push_str(&mut self, s: &str) -> bool {
306 let mut replacer = None;
307 let answer;
308 match &mut *self.inner.borrow_mut() {
309 fixed(fs) if fs.len() + s.len() < N => {
310 fs.push(s);
311 answer = true;
312 }
313 fixed(fs) => {
314 let fss = fs.to_string() + s;
315 replacer = Some(owned(fss));
316 answer = false;
318 }
319 owned(ns) => {
320 ns.push_str(s);
321 answer = false;
322 }
323 } if let Some(r) = replacer {
325 self.inner.replace(r);
326 }
327 answer
328 } pub fn push(&mut self, c: char) -> bool {
334 let clen = c.len_utf8();
335 let answer;
336 let mut replacer = None;
337 match &mut *self.inner.borrow_mut() {
338 owned(s) => {
339 s.push(c);
340 answer = false;
341 }
342 fixed(s) if s.len() + clen >= N => {
343 let mut fss = s.to_string();
344 fss.push(c);
345 replacer = Some(owned(fss));
346 answer = false;
348 }
349 fixed(s) => {
350 let mut buf = [0u8; 4];
351 let bstr = c.encode_utf8(&mut buf);
352 s.push(bstr);
353 answer = true;
354 }
355 } if let Some(r) = replacer {
357 self.inner.replace(r);
358 }
359 answer
360 } pub fn push_char(&mut self, c: char) -> bool {
364 self.push(c)
365 }
366
367 pub fn pop(&mut self) -> Option<char> {
369 if self.len() == 0 {
370 return None;
371 }
372 let answer;
373 let mut replacer = None;
374 match &mut *self.inner.borrow_mut() {
375 fixed(s) => {
376 answer = s.pop_char();
377 }
378 owned(s) if s.len() > N => {
379 answer = s.pop();
380 }
381 owned(s) => {
382 answer = s.pop();
384 replacer = Some(fixed(tstr::from(&s)));
385 }
386 } if let Some(r) = replacer {
388 self.inner.replace(r);
389 }
390 answer
391 } pub fn pop_char(&mut self) -> Option<char> {
395 self.pop()
396 }
397
398 pub fn truncate(&mut self, n: usize) -> bool {
404 let mut replacer = None;
405 let answer;
406 match &mut *self.inner.borrow_mut() {
407 fixed(fs) if n < fs.len() => {
408 fs.truncate_bytes(n);
409 answer = true;
410 }
411 fixed(_) => {
412 answer = true;
413 }
414 owned(s) if n < N => {
415 assert!(s.is_char_boundary(n));
416 replacer = Some(fixed(tstr::<N>::from(&s[..n])));
417 answer = true;
418 }
419 owned(s) => {
420 if n < s.len() {
421 s.truncate(n);
422 }
423 answer = false;
424 }
425 } if let Some(r) = replacer {
427 self.inner.replace(r);
428 }
429 answer
430 } pub fn clear(&mut self) {
434 let mut replacer = None;
435 match &mut *self.inner.borrow_mut() {
436 fixed(s) => {
437 s.clear();
438 }
439 owned(s) => {
440 replacer = Some(fixed(tstr::default()));
441 }
442 }
443 if let Some(r) = replacer {
444 self.inner.replace(r);
445 }
446 } pub fn substr(&self, start: usize, end: usize) -> Sharedstr<N> {
450 match &*self.inner.borrow() {
451 fixed(s) => Sharedstr {
452 inner: Rc::new(RefCell::new(fixed(s.substr(start, end)))),
453 },
454 owned(s) => Self::from(&s[start..end]),
455 }
456 } pub fn split_off(&mut self) -> String {
469 let answer;
470 let mut replacer = None;
471 match &mut *self.inner.borrow_mut() {
472 fixed(s) => {
473 answer = String::default();
474 }
475 owned(s) => {
476 answer = String::from(&s[N - 1..]);
477 replacer = Some(fixed(tstr::<N>::from(&s[..N - 1])));
478 }
479 } if let Some(r) = replacer {
481 self.inner.replace(r);
482 }
483 answer
484 } pub fn equals<T: AsRef<str>>(&self, other: &T) -> bool {
488 self == other.as_ref()
489 }
490
491 pub fn ptr_eq(&self, other: &Self) -> bool {
494 Rc::ptr_eq(&self.inner, &other.inner)
495 }
496
497 pub fn deep_clone(&self) -> Self {
499 Sharedstr::from(self.as_str())
500 }
501
502 pub fn ptr_count(&self) -> usize {
505 Rc::strong_count(&self.inner)
506 }
507
508 pub fn make_ascii_lowercase(&mut self) {
510 match &mut *self.inner.borrow_mut() {
511 fixed(s) => {
512 s.make_ascii_lowercase();
513 }
514 owned(s) => {
515 s.as_mut_str().make_ascii_lowercase();
516 }
517 } } pub fn make_ascii_uppercase(&mut self) {
522 match &mut *self.inner.borrow_mut() {
523 fixed(s) => {
524 s.make_ascii_uppercase();
525 }
526 owned(s) => {
527 s.as_mut_str().make_ascii_uppercase();
528 }
529 } }
531
532 pub fn case_insensitive_eq<TA>(&self, other: TA) -> bool
535 where
536 TA: AsRef<str>,
537 {
538 if self.len() != other.as_ref().len() {
539 return false;
540 }
541 let obytes = other.as_ref().as_bytes();
542 let sbytes = self.as_bytes();
543 for i in 0..self.len() {
544 let mut c = sbytes[i];
545 if (c > 64 && c < 91) {
546 c = c | 32;
547 } let mut d = obytes[i];
549 if (d > 64 && d < 91) {
550 d = d | 32;
551 } if c != d {
553 return false;
554 }
555 } true
557 } pub fn from_utf16(v: &[u16]) -> Result<Self, Self> {
563 let mut s = Self::new();
564 for c in char::decode_utf16(v.iter().cloned()) {
565 if let Ok(c1) = c {
566 if !s.push_char(c1) {
567 return Err(s);
568 }
569 } else {
570 return Err(s);
571 }
572 }
573 Ok(s)
574 } } impl<const N: usize> Default for Sharedstr<N> {
578 fn default() -> Self {
579 Sharedstr {
580 inner: Rc::new(RefCell::new(fixed(tstr::<N>::default()))),
581 }
582 }
583}
584
585#[cfg(feature = "flex-str")]
586use crate::Flexstr;
587#[cfg(feature = "flex-str")]
588impl<const N: usize> Sharedstr<N> {
589 pub fn to_flexstr(self) -> Result<Flexstr<N>, Sharedstr<N>> {
594 extern crate std;
595 use crate::shared_structs::Strunion::*;
596 use std::rc::Rc;
597 match Rc::try_unwrap(self.inner) {
598 Ok(x) => {
599 match x.into_inner() {
600 fixed(s) => Ok(Flexstr::from_tstr(s)),
601 owned(s) => Ok(Flexstr::from_string(s)),
602 } }
604 Err(r) => Err(Sharedstr { inner: r }),
605 } } } impl<const N: usize> core::ops::Deref for Sharedstr<N> {
610 type Target = str;
611 fn deref(&self) -> &Self::Target {
612 self.as_str()
613 }
614}
615
616impl<T: AsRef<str> + ?Sized, const N: usize> core::convert::From<&T> for Sharedstr<N> {
625 fn from(s: &T) -> Self {
626 Self::make(s.as_ref())
627 }
628}
629impl<T: AsMut<str> + ?Sized, const N: usize> core::convert::From<&mut T> for Sharedstr<N> {
630 fn from(s: &mut T) -> Self {
631 Self::make(s.as_mut())
632 }
633}
634
635impl<const N: usize> core::cmp::PartialOrd for Sharedstr<N> {
636 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
637 Some(self.cmp(other))
638 }
639}
640
641impl<const N: usize> core::cmp::Ord for Sharedstr<N> {
642 fn cmp(&self, other: &Self) -> Ordering {
643 self.as_str().cmp(other.as_str())
644 }
645}
646
647impl<const N: usize> core::convert::AsRef<str> for Sharedstr<N> {
648 fn as_ref(&self) -> &str {
649 self.as_str()
650 }
651}
652impl<const N: usize> core::convert::AsMut<str> for Sharedstr<N> {
653 fn as_mut(&mut self) -> &mut str {
654 unsafe {
655 match self.inner.as_ptr().as_mut().unwrap() {
656 fixed(f) => f.as_mut(),
657 owned(s) => s.as_mut(),
658 } } } }
662
663impl<const N: usize> PartialEq<&str> for Sharedstr<N> {
664 fn eq(&self, other: &&str) -> bool {
665 &self.to_str() == other } }
668
669impl<const N: usize> PartialEq<&str> for &Sharedstr<N> {
670 fn eq(&self, other: &&str) -> bool {
671 &self.to_str() == other
672 } }
674impl<'t, const N: usize> PartialEq<Sharedstr<N>> for &'t str {
675 fn eq(&self, other: &Sharedstr<N>) -> bool {
676 &other.to_str() == self
677 }
678}
679impl<'t, const N: usize> PartialEq<&Sharedstr<N>> for &'t str {
680 fn eq(&self, other: &&Sharedstr<N>) -> bool {
681 &other.to_str() == self
682 }
683}
684
685impl<const N: usize> core::fmt::Debug for Sharedstr<N> {
686 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
687 f.pad(&self.to_str())
688 }
689} impl<const N: usize> core::fmt::Display for Sharedstr<N> {
692 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
693 f.pad(self.to_str())
695 }
696}
697
698impl<const N: usize> core::fmt::Write for Sharedstr<N> {
699 fn write_str(&mut self, s: &str) -> core::fmt::Result {
700 self.push_str(s);
701 Ok(())
702 } } impl<const N: usize> core::convert::From<String> for Sharedstr<N> {
706 fn from(s: String) -> Self {
709 if s.len() >= N {
710 Sharedstr {
711 inner: Rc::new(RefCell::new(owned(s))),
712 }
713 } else {
714 Sharedstr {
715 inner: Rc::new(RefCell::new(fixed(tstr::<N>::from(&s[..])))),
716 }
717 }
718 }
719} impl<const M: usize> Sharedstr<M> {
722 pub fn resize<const N: usize>(&self) -> Sharedstr<N> {
734 Sharedstr::from(self)
735 }
736}
737
738impl<const N: usize, TA: AsRef<str>> Add<TA> for &Sharedstr<N> {
739 type Output = Sharedstr<N>;
740 fn add(self, other: TA) -> Self::Output {
741 match (&*self.inner.borrow(), other.as_ref()) {
742 (owned(a), b) => {
743 let mut a2 = a.clone();
744 a2.push_str(other.as_ref());
745 Sharedstr {
746 inner: Rc::new(RefCell::new(owned(a2))),
747 }
748 }
749 (fixed(a), b) if a.len() + b.len() >= N => {
750 let mut a2 = a.to_string();
751 a2.push_str(b);
752 Sharedstr {
753 inner: Rc::new(RefCell::new(owned(a2))),
754 }
755 }
756 (fixed(a), b) => {
757 let mut a2 = *a; a2.push(b);
759 Sharedstr {
760 inner: Rc::new(RefCell::new(fixed(a2))),
761 }
762 }
763 } }
765} impl<const N: usize> Add<&Sharedstr<N>> for &str {
768 type Output = Sharedstr<N>;
769 fn add(self, other: &Sharedstr<N>) -> Sharedstr<N> {
770 let mut a2 = Sharedstr::from(self);
771 a2.push_str(other);
772 a2
773 }
774} impl<const N: usize> Add<Sharedstr<N>> for &str {
777 type Output = Sharedstr<N>;
778 fn add(self, other: Sharedstr<N>) -> Sharedstr<N> {
779 let mut a2 = Sharedstr::from(self);
780 a2.push_str(&other);
781 a2
782 }
783} impl<const N: usize> core::hash::Hash for Sharedstr<N> {
786 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
787 self.as_ref().hash(state);
788 }
789} impl<const N: usize> core::cmp::PartialEq for Sharedstr<N> {
792 fn eq(&self, other: &Self) -> bool {
793 self.as_ref() == other.as_ref()
794 }
795} impl<const N: usize> core::str::FromStr for Sharedstr<N> {
798 type Err = &'static str;
799 fn from_str(s: &str) -> Result<Self, Self::Err> {
800 Ok(Sharedstr::from(s))
801 }
802}
803
804pub type sharedstr8 = Sharedstr<8>;
806pub type sharedstr16 = Sharedstr<16>;
807pub type sharedstr32 = Sharedstr<32>;
808pub type sharedstr64 = Sharedstr<64>;
809pub type sharedstr128 = Sharedstr<128>;
810pub type sharedstr256 = Sharedstr<256>;