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 {
122 unsafe {
123 match self.inner.as_ptr().as_ref().unwrap() {
124 fixed(s) => s.as_str_safe(),
125 owned(s) => Ok(s.as_str()),
126 } } }
129
130 pub fn new() -> Self {
132 Self::default()
133 }
134
135 pub fn charlen(&self) -> usize {
138 match &*self.inner.borrow() {
139 fixed(s) => s.charlen(),
140 owned(s) => s.chars().count(),
141 } } pub fn to_str(&self) -> &str {
146 self.as_str()
147 } pub fn get_str(&self) -> Option<tstr<N>> {
159 if let fixed(s) = &*self.inner.borrow() {
160 Some(*s)
161 } else {
162 None
163 }
164 } pub fn take_string(&mut self) -> Option<String> {
169 if let (ss @ owned(_)) = &mut *self.inner.borrow_mut() {
170 let mut temp = fixed(tstr::new());
171
172 core::mem::swap(ss, &mut temp);
173 if let owned(t) = temp {
174 Some(t)
175 } else {
176 None
177 }
178 } else {
179 None
180 }
181 } pub fn to_string(self) -> String {
185 match &*self.inner.borrow() {
186 fixed(s) => s.to_string(),
187 owned(s) => s.clone(),
188 } } pub fn nth(&self, n: usize) -> Option<char> {
193 self.to_str().chars().nth(n)
194 }
195
196 pub fn nth_bytechar(&self, n: usize) -> char {
200 match &*self.inner.borrow() {
201 fixed(s) => s.nth_ascii(n),
202 owned(s) => s.as_bytes()[n] as char,
203 }
204 } pub fn nth_ascii(&self, n: usize) -> char {
208 self.nth_bytechar(n)
209 }
210
211 pub fn as_bytes(&self) -> &[u8] {
215 self.as_str().as_bytes()
216 } pub fn set(&mut self, i: usize, c: char) -> bool {
223 match &mut *self.inner.borrow_mut() {
224 fixed(s) => s.set(i, c),
225 owned(s) => unsafe {
226 let ref mut cbuf = [0u8; 4];
227 c.encode_utf8(cbuf);
228 let clen = c.len_utf8();
229 if let Some((bi, rc)) = s.char_indices().nth(i) {
230 if clen == rc.len_utf8() {
231 s.as_bytes_mut()[bi..bi + clen].copy_from_slice(&cbuf[..clen]);
232 return true;
235 }
236 }
237 return false;
238 },
239 } } pub fn is_fixed(&self) -> bool {
244 match &*self.inner.borrow() {
245 fixed(_) => true,
246 owned(_) => false,
247 }
248 } pub fn is_owned(&self) -> bool {
252 !self.is_fixed()
253 }
254
255 pub fn if_fixed<F>(&mut self, f: F)
258 where
259 F: FnOnce(&mut tstr<N>),
260 {
261 if let fixed(s) = &mut *self.inner.borrow_mut() {
262 f(s);
263 }
264 }
265
266 pub fn if_owned<F>(&mut self, f: F)
269 where
270 F: FnOnce(&mut str),
271 {
272 if let owned(s) = &mut *self.inner.borrow_mut() {
273 f(s);
274 }
275 }
276
277 pub fn map_or<F, G, U>(&self, f: F, g: G) -> U
280 where
281 F: FnOnce(&tstr<N>) -> U,
282 G: FnOnce(&str) -> U,
283 {
284 match &*self.inner.borrow() {
285 fixed(s) => f(s),
286 owned(s) => g(&s[..]),
287 } } pub fn map_or_mut<F, G, U>(&mut self, f: &mut F, g: &mut G) -> U
292 where
293 F: FnMut(&mut tstr<N>) -> U,
294 G: FnMut(&mut str) -> U,
295 {
296 match &mut *self.inner.borrow_mut() {
297 fixed(s) => f(s),
298 owned(s) => g(&mut s[..]),
299 } } pub fn push_str(&mut self, s: &str) -> bool {
307 let mut replacer = None;
308 let answer;
309 match &mut *self.inner.borrow_mut() {
310 fixed(fs) if fs.len() + s.len() < N => {
311 fs.push(s);
312 answer = true;
313 }
314 fixed(fs) => {
315 let fss = fs.to_string() + s;
316 replacer = Some(owned(fss));
317 answer = false;
319 }
320 owned(ns) => {
321 ns.push_str(s);
322 answer = false;
323 }
324 } if let Some(r) = replacer {
326 self.inner.replace(r);
327 }
328 answer
329 } pub fn push(&mut self, c: char) -> bool {
335 let clen = c.len_utf8();
336 let answer;
337 let mut replacer = None;
338 match &mut *self.inner.borrow_mut() {
339 owned(s) => {
340 s.push(c);
341 answer = false;
342 }
343 fixed(s) if s.len() + clen >= N => {
344 let mut fss = s.to_string();
345 fss.push(c);
346 replacer = Some(owned(fss));
347 answer = false;
349 }
350 fixed(s) => {
351 let mut buf = [0u8; 4];
352 let bstr = c.encode_utf8(&mut buf);
353 s.push(bstr);
354 answer = true;
355 }
356 } if let Some(r) = replacer {
358 self.inner.replace(r);
359 }
360 answer
361 } pub fn push_char(&mut self, c: char) -> bool {
365 self.push(c)
366 }
367
368 pub fn pop(&mut self) -> Option<char> {
370 if self.len() == 0 {
371 return None;
372 }
373 let answer;
374 let mut replacer = None;
375 match &mut *self.inner.borrow_mut() {
376 fixed(s) => {
377 answer = s.pop_char();
378 }
379 owned(s) if s.len() > N => {
380 answer = s.pop();
381 }
382 owned(s) => {
383 answer = s.pop();
385 replacer = Some(fixed(tstr::from(&s)));
386 }
387 } if let Some(r) = replacer {
389 self.inner.replace(r);
390 }
391 answer
392 } pub fn pop_char(&mut self) -> Option<char> {
396 self.pop()
397 }
398
399 pub fn truncate(&mut self, n: usize) -> bool {
405 let mut replacer = None;
406 let answer;
407 match &mut *self.inner.borrow_mut() {
408 fixed(fs) if n < fs.len() => {
409 fs.truncate_bytes(n);
410 answer = true;
411 }
412 fixed(_) => {
413 answer = true;
414 }
415 owned(s) if n < N => {
416 assert!(s.is_char_boundary(n));
417 replacer = Some(fixed(tstr::<N>::from(&s[..n])));
418 answer = true;
419 }
420 owned(s) => {
421 if n < s.len() {
422 s.truncate(n);
423 }
424 answer = false;
425 }
426 } if let Some(r) = replacer {
428 self.inner.replace(r);
429 }
430 answer
431 } pub fn clear(&mut self) {
435 let mut replacer = None;
436 match &mut *self.inner.borrow_mut() {
437 fixed(s) => {
438 s.clear();
439 }
440 owned(s) => {
441 replacer = Some(fixed(tstr::default()));
442 }
443 }
444 if let Some(r) = replacer {
445 self.inner.replace(r);
446 }
447 } pub fn substr(&self, start: usize, end: usize) -> Sharedstr<N> {
451 match &*self.inner.borrow() {
452 fixed(s) => Sharedstr {
453 inner: Rc::new(RefCell::new(fixed(s.substr(start, end)))),
454 },
455 owned(s) => Self::from(&s[start..end]),
456 }
457 } pub fn split_off(&mut self) -> String {
470 let answer;
471 let mut replacer = None;
472 match &mut *self.inner.borrow_mut() {
473 fixed(s) => {
474 answer = String::default();
475 }
476 owned(s) => {
477 answer = String::from(&s[N - 1..]);
478 replacer = Some(fixed(tstr::<N>::from(&s[..N - 1])));
479 }
480 } if let Some(r) = replacer {
482 self.inner.replace(r);
483 }
484 answer
485 } pub fn equals<T: AsRef<str>>(&self, other: &T) -> bool {
489 self == other.as_ref()
490 }
491
492 pub fn ptr_eq(&self, other: &Self) -> bool {
495 Rc::ptr_eq(&self.inner, &other.inner)
496 }
497
498 pub fn deep_clone(&self) -> Self {
500 Sharedstr::from(self.as_str())
501 }
502
503 pub fn ptr_count(&self) -> usize {
506 Rc::strong_count(&self.inner)
507 }
508
509 pub fn make_ascii_lowercase(&mut self) {
511 match &mut *self.inner.borrow_mut() {
512 fixed(s) => {
513 s.make_ascii_lowercase();
514 }
515 owned(s) => {
516 s.as_mut_str().make_ascii_lowercase();
517 }
518 } } pub fn make_ascii_uppercase(&mut self) {
523 match &mut *self.inner.borrow_mut() {
524 fixed(s) => {
525 s.make_ascii_uppercase();
526 }
527 owned(s) => {
528 s.as_mut_str().make_ascii_uppercase();
529 }
530 } }
532
533 pub fn case_insensitive_eq<TA>(&self, other: TA) -> bool
536 where
537 TA: AsRef<str>,
538 {
539 if self.len() != other.as_ref().len() {
540 return false;
541 }
542 let obytes = other.as_ref().as_bytes();
543 let sbytes = self.as_bytes();
544 for i in 0..self.len() {
545 let mut c = sbytes[i];
546 if (c > 64 && c < 91) {
547 c = c | 32;
548 } let mut d = obytes[i];
550 if (d > 64 && d < 91) {
551 d = d | 32;
552 } if c != d {
554 return false;
555 }
556 } true
558 } pub fn from_utf16(v: &[u16]) -> Result<Self, Self> {
564 let mut s = Self::new();
565 for c in char::decode_utf16(v.iter().cloned()) {
566 if let Ok(c1) = c {
567 if !s.push_char(c1) {
568 return Err(s);
569 }
570 } else {
571 return Err(s);
572 }
573 }
574 Ok(s)
575 } } impl<const N: usize> Default for Sharedstr<N> {
579 fn default() -> Self {
580 Sharedstr {
581 inner: Rc::new(RefCell::new(fixed(tstr::<N>::default()))),
582 }
583 }
584}
585
586#[cfg(feature = "flex-str")]
587use crate::Flexstr;
588#[cfg(feature = "flex-str")]
589impl<const N: usize> Sharedstr<N> {
590 pub fn to_flexstr(self) -> Result<Flexstr<N>, Sharedstr<N>> {
595 extern crate std;
596 use crate::shared_structs::Strunion::*;
597 use std::rc::Rc;
598 match Rc::try_unwrap(self.inner) {
599 Ok(x) => {
600 match x.into_inner() {
601 fixed(s) => Ok(Flexstr::from_tstr(s)),
602 owned(s) => Ok(Flexstr::from_string(s)),
603 } }
605 Err(r) => Err(Sharedstr { inner: r }),
606 } } } impl<const N: usize> core::ops::Deref for Sharedstr<N> {
611 type Target = str;
612 fn deref(&self) -> &Self::Target {
613 self.as_str()
614 }
615}
616
617impl<T: AsRef<str> + ?Sized, const N: usize> core::convert::From<&T> for Sharedstr<N> {
626 fn from(s: &T) -> Self {
627 Self::make(s.as_ref())
628 }
629}
630impl<T: AsMut<str> + ?Sized, const N: usize> core::convert::From<&mut T> for Sharedstr<N> {
631 fn from(s: &mut T) -> Self {
632 Self::make(s.as_mut())
633 }
634}
635
636impl<const N: usize> core::cmp::PartialOrd for Sharedstr<N> {
637 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
638 Some(self.cmp(other))
639 }
640}
641
642impl<const N: usize> core::cmp::Ord for Sharedstr<N> {
643 fn cmp(&self, other: &Self) -> Ordering {
644 self.as_str().cmp(other.as_str())
645 }
646}
647
648impl<const N: usize> core::convert::AsRef<str> for Sharedstr<N> {
649 fn as_ref(&self) -> &str {
650 self.as_str()
651 }
652}
653impl<const N: usize> core::convert::AsMut<str> for Sharedstr<N> {
654 fn as_mut(&mut self) -> &mut str {
655 unsafe {
656 match self.inner.as_ptr().as_mut().unwrap() {
657 fixed(f) => f.as_mut(),
658 owned(s) => s.as_mut(),
659 } } } }
663
664impl<const N: usize> PartialEq<&str> for Sharedstr<N> {
665 fn eq(&self, other: &&str) -> bool {
666 &self.to_str() == other } }
669
670impl<const N: usize> PartialEq<&str> for &Sharedstr<N> {
671 fn eq(&self, other: &&str) -> bool {
672 &self.to_str() == other
673 } }
675impl<'t, const N: usize> PartialEq<Sharedstr<N>> for &'t str {
676 fn eq(&self, other: &Sharedstr<N>) -> bool {
677 &other.to_str() == self
678 }
679}
680impl<'t, const N: usize> PartialEq<&Sharedstr<N>> for &'t str {
681 fn eq(&self, other: &&Sharedstr<N>) -> bool {
682 &other.to_str() == self
683 }
684}
685
686impl<const N: usize> core::fmt::Debug for Sharedstr<N> {
687 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
688 f.pad(&self.to_str())
689 }
690} impl<const N: usize> core::fmt::Display for Sharedstr<N> {
693 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
694 f.pad(self.to_str())
696 }
697}
698
699impl<const N: usize> core::fmt::Write for Sharedstr<N> {
700 fn write_str(&mut self, s: &str) -> core::fmt::Result {
701 self.push_str(s);
702 Ok(())
703 } } impl<const N: usize> core::convert::From<String> for Sharedstr<N> {
707 fn from(s: String) -> Self {
710 if s.len() >= N {
711 Sharedstr {
712 inner: Rc::new(RefCell::new(owned(s))),
713 }
714 } else {
715 Sharedstr {
716 inner: Rc::new(RefCell::new(fixed(tstr::<N>::from(&s[..])))),
717 }
718 }
719 }
720} impl<const M: usize> Sharedstr<M> {
723 pub fn resize<const N: usize>(&self) -> Sharedstr<N> {
735 Sharedstr::from(self)
736 }
737}
738
739impl<const N: usize, TA: AsRef<str>> Add<TA> for &Sharedstr<N> {
740 type Output = Sharedstr<N>;
741 fn add(self, other: TA) -> Self::Output {
742 match (&*self.inner.borrow(), other.as_ref()) {
743 (owned(a), b) => {
744 let mut a2 = a.clone();
745 a2.push_str(other.as_ref());
746 Sharedstr {
747 inner: Rc::new(RefCell::new(owned(a2))),
748 }
749 }
750 (fixed(a), b) if a.len() + b.len() >= N => {
751 let mut a2 = a.to_string();
752 a2.push_str(b);
753 Sharedstr {
754 inner: Rc::new(RefCell::new(owned(a2))),
755 }
756 }
757 (fixed(a), b) => {
758 let mut a2 = *a; a2.push(b);
760 Sharedstr {
761 inner: Rc::new(RefCell::new(fixed(a2))),
762 }
763 }
764 } }
766} impl<const N: usize> Add<&Sharedstr<N>> for &str {
769 type Output = Sharedstr<N>;
770 fn add(self, other: &Sharedstr<N>) -> Sharedstr<N> {
771 let mut a2 = Sharedstr::from(self);
772 a2.push_str(other);
773 a2
774 }
775} impl<const N: usize> Add<Sharedstr<N>> for &str {
778 type Output = Sharedstr<N>;
779 fn add(self, other: Sharedstr<N>) -> Sharedstr<N> {
780 let mut a2 = Sharedstr::from(self);
781 a2.push_str(&other);
782 a2
783 }
784} impl<const N: usize> core::hash::Hash for Sharedstr<N> {
787 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
788 self.as_ref().hash(state);
789 }
790} impl<const N: usize> core::cmp::PartialEq for Sharedstr<N> {
793 fn eq(&self, other: &Self) -> bool {
794 self.as_ref() == other.as_ref()
795 }
796} impl<const N: usize> core::str::FromStr for Sharedstr<N> {
799 type Err = &'static str;
800 fn from_str(s: &str) -> Result<Self, Self::Err> {
801 Ok(Sharedstr::from(s))
802 }
803}
804
805pub type sharedstr8 = Sharedstr<8>;
807pub type sharedstr16 = Sharedstr<16>;
808pub type sharedstr32 = Sharedstr<32>;
809pub type sharedstr64 = Sharedstr<64>;
810pub type sharedstr128 = Sharedstr<128>;
811pub type sharedstr256 = Sharedstr<256>;