spo_rhai/types/
immutable_string.rs1use crate::func::{shared_get_mut, shared_make_mut, shared_take};
4use crate::{Shared, SmartString};
5#[cfg(feature = "no_std")]
6use std::prelude::v1::*;
7use std::{
8 borrow::Borrow,
9 cmp::Ordering,
10 fmt,
11 hash::Hash,
12 iter::FromIterator,
13 ops::{Add, AddAssign, Deref, Sub, SubAssign},
14 str::FromStr,
15};
16
17#[derive(Clone, Eq, Ord, Hash, Default)]
50pub struct ImmutableString(Shared<SmartString>);
51
52impl Deref for ImmutableString {
53 type Target = str;
54
55 #[inline(always)]
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl AsRef<str> for ImmutableString {
62 #[inline(always)]
63 #[must_use]
64 fn as_ref(&self) -> &str {
65 &self.0
66 }
67}
68
69impl AsRef<SmartString> for ImmutableString {
70 #[inline(always)]
71 #[must_use]
72 fn as_ref(&self) -> &SmartString {
73 &self.0
74 }
75}
76
77impl Borrow<str> for ImmutableString {
78 #[inline(always)]
79 #[must_use]
80 fn borrow(&self) -> &str {
81 &self.0
82 }
83}
84
85impl Borrow<SmartString> for ImmutableString {
86 #[inline(always)]
87 #[must_use]
88 fn borrow(&self) -> &SmartString {
89 &self.0
90 }
91}
92
93impl From<&Self> for ImmutableString {
94 #[inline(always)]
95 fn from(value: &Self) -> Self {
96 Self(value.0.clone())
97 }
98}
99
100impl From<&str> for ImmutableString {
101 #[inline(always)]
102 fn from(value: &str) -> Self {
103 let value: SmartString = value.into();
104 Self(value.into())
105 }
106}
107
108impl From<Box<str>> for ImmutableString {
109 #[inline(always)]
110 fn from(value: Box<str>) -> Self {
111 let value: SmartString = value.into();
112 Self(value.into())
113 }
114}
115impl From<&String> for ImmutableString {
116 #[inline(always)]
117 fn from(value: &String) -> Self {
118 let value: SmartString = value.into();
119 Self(value.into())
120 }
121}
122impl From<String> for ImmutableString {
123 #[inline(always)]
124 fn from(value: String) -> Self {
125 let value: SmartString = value.into();
126 Self(value.into())
127 }
128}
129impl From<&SmartString> for ImmutableString {
130 #[inline(always)]
131 fn from(value: &SmartString) -> Self {
132 Self(value.clone().into())
133 }
134}
135impl From<SmartString> for ImmutableString {
136 #[inline(always)]
137 fn from(value: SmartString) -> Self {
138 Self(value.into())
139 }
140}
141impl From<&ImmutableString> for SmartString {
142 #[inline(always)]
143 fn from(value: &ImmutableString) -> Self {
144 value.0.as_ref().clone()
145 }
146}
147impl From<ImmutableString> for SmartString {
148 #[inline(always)]
149 fn from(mut value: ImmutableString) -> Self {
150 let _ = value.make_mut(); shared_take(value.0) }
153}
154impl From<&ImmutableString> for String {
155 #[inline(always)]
156 fn from(value: &ImmutableString) -> Self {
157 value.0.as_ref().to_string()
158 }
159}
160impl From<ImmutableString> for String {
161 #[inline(always)]
162 fn from(value: ImmutableString) -> Self {
163 value.into_owned()
164 }
165}
166impl From<&ImmutableString> for Box<str> {
167 #[inline(always)]
168 fn from(value: &ImmutableString) -> Self {
169 value.0.as_str().into()
170 }
171}
172impl From<ImmutableString> for Box<str> {
173 #[inline(always)]
174 fn from(value: ImmutableString) -> Self {
175 value.0.as_str().into()
176 }
177}
178
179impl FromStr for ImmutableString {
180 type Err = ();
181
182 #[inline(always)]
183 fn from_str(s: &str) -> Result<Self, Self::Err> {
184 let s: SmartString = s.into();
185 Ok(Self(s.into()))
186 }
187}
188
189impl FromIterator<char> for ImmutableString {
190 #[inline]
191 #[must_use]
192 fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
193 Self(iter.into_iter().collect::<SmartString>().into())
194 }
195}
196
197impl<'a> FromIterator<&'a char> for ImmutableString {
198 #[inline]
199 #[must_use]
200 fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
201 Self(iter.into_iter().copied().collect::<SmartString>().into())
202 }
203}
204
205impl<'a> FromIterator<&'a str> for ImmutableString {
206 #[inline]
207 #[must_use]
208 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
209 Self(iter.into_iter().collect::<SmartString>().into())
210 }
211}
212
213impl FromIterator<String> for ImmutableString {
214 #[inline]
215 #[must_use]
216 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
217 Self(iter.into_iter().collect::<SmartString>().into())
218 }
219}
220
221impl FromIterator<SmartString> for ImmutableString {
222 #[inline]
223 #[must_use]
224 fn from_iter<T: IntoIterator<Item = SmartString>>(iter: T) -> Self {
225 Self(iter.into_iter().collect::<SmartString>().into())
226 }
227}
228
229impl fmt::Display for ImmutableString {
230 #[inline(always)]
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 fmt::Display::fmt(self.as_str(), f)
233 }
234}
235
236impl fmt::Debug for ImmutableString {
237 #[cold]
238 #[inline(never)]
239 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240 fmt::Debug::fmt(self.as_str(), f)
241 }
242}
243
244impl Add for ImmutableString {
245 type Output = Self;
246
247 #[inline]
248 fn add(mut self, rhs: Self) -> Self::Output {
249 if rhs.is_empty() {
250 self
251 } else if self.is_empty() {
252 rhs
253 } else {
254 self.make_mut().push_str(rhs.as_str());
255 self
256 }
257 }
258}
259
260impl Add for &ImmutableString {
261 type Output = ImmutableString;
262
263 #[inline]
264 fn add(self, rhs: Self) -> Self::Output {
265 if rhs.is_empty() {
266 self.clone()
267 } else if self.is_empty() {
268 rhs.clone()
269 } else {
270 let mut s = self.clone();
271 s.make_mut().push_str(rhs.as_str());
272 s
273 }
274 }
275}
276
277impl Add<&Self> for ImmutableString {
278 type Output = Self;
279
280 #[inline]
281 fn add(mut self, rhs: &Self) -> Self::Output {
282 if rhs.is_empty() {
283 self
284 } else if self.is_empty() {
285 rhs.clone()
286 } else {
287 self.make_mut().push_str(rhs.as_str());
288 self
289 }
290 }
291}
292
293impl Add<ImmutableString> for &ImmutableString {
294 type Output = ImmutableString;
295
296 #[inline]
297 fn add(self, rhs: ImmutableString) -> Self::Output {
298 if rhs.is_empty() {
299 self.clone()
300 } else if self.is_empty() {
301 rhs
302 } else {
303 let mut s = self.clone();
304 s.make_mut().push_str(rhs.as_str());
305 s
306 }
307 }
308}
309
310impl AddAssign<Self> for ImmutableString {
311 #[inline]
312 fn add_assign(&mut self, rhs: Self) {
313 if !rhs.is_empty() {
314 if self.is_empty() {
315 self.0 = rhs.0;
316 } else {
317 self.make_mut().push_str(&rhs);
318 }
319 }
320 }
321}
322
323impl AddAssign<&Self> for ImmutableString {
324 #[inline]
325 fn add_assign(&mut self, rhs: &Self) {
326 if !rhs.is_empty() {
327 if self.is_empty() {
328 self.0 = rhs.0.clone();
329 } else {
330 self.make_mut().push_str(rhs.as_str());
331 }
332 }
333 }
334}
335
336impl Add<&str> for ImmutableString {
337 type Output = Self;
338
339 #[inline]
340 fn add(mut self, rhs: &str) -> Self::Output {
341 if !rhs.is_empty() {
342 self.make_mut().push_str(rhs);
343 }
344 self
345 }
346}
347
348impl Add<&str> for &ImmutableString {
349 type Output = ImmutableString;
350
351 #[inline]
352 fn add(self, rhs: &str) -> Self::Output {
353 if rhs.is_empty() {
354 self.clone()
355 } else {
356 let mut s = self.clone();
357 s.make_mut().push_str(rhs);
358 s
359 }
360 }
361}
362
363impl AddAssign<&str> for ImmutableString {
364 #[inline]
365 fn add_assign(&mut self, rhs: &str) {
366 if !rhs.is_empty() {
367 self.make_mut().push_str(rhs);
368 }
369 }
370}
371
372impl Add<String> for ImmutableString {
373 type Output = Self;
374
375 #[inline]
376 fn add(mut self, rhs: String) -> Self::Output {
377 if rhs.is_empty() {
378 self
379 } else if self.is_empty() {
380 rhs.into()
381 } else {
382 self.make_mut().push_str(&rhs);
383 self
384 }
385 }
386}
387
388impl Add<String> for &ImmutableString {
389 type Output = ImmutableString;
390
391 #[inline]
392 fn add(self, rhs: String) -> Self::Output {
393 if rhs.is_empty() {
394 self.clone()
395 } else if self.is_empty() {
396 rhs.into()
397 } else {
398 let mut s = self.clone();
399 s.make_mut().push_str(&rhs);
400 s
401 }
402 }
403}
404
405impl AddAssign<String> for ImmutableString {
406 #[inline]
407 fn add_assign(&mut self, rhs: String) {
408 if !rhs.is_empty() {
409 if self.is_empty() {
410 let rhs: SmartString = rhs.into();
411 self.0 = rhs.into();
412 } else {
413 self.make_mut().push_str(&rhs);
414 }
415 }
416 }
417}
418
419impl Add<char> for ImmutableString {
420 type Output = Self;
421
422 #[inline]
423 fn add(mut self, rhs: char) -> Self::Output {
424 self.make_mut().push(rhs);
425 self
426 }
427}
428
429impl Add<char> for &ImmutableString {
430 type Output = ImmutableString;
431
432 #[inline]
433 fn add(self, rhs: char) -> Self::Output {
434 let mut s = self.clone();
435 s.make_mut().push(rhs);
436 s
437 }
438}
439
440impl AddAssign<char> for ImmutableString {
441 #[inline]
442 fn add_assign(&mut self, rhs: char) {
443 self.make_mut().push(rhs);
444 }
445}
446
447impl Sub for ImmutableString {
448 type Output = Self;
449
450 #[inline]
451 fn sub(self, rhs: Self) -> Self::Output {
452 if rhs.is_empty() {
453 self
454 } else if self.is_empty() {
455 rhs
456 } else {
457 self.replace(rhs.as_str(), "").into()
458 }
459 }
460}
461
462impl Sub for &ImmutableString {
463 type Output = ImmutableString;
464
465 #[inline]
466 fn sub(self, rhs: Self) -> Self::Output {
467 if rhs.is_empty() {
468 self.clone()
469 } else if self.is_empty() {
470 rhs.clone()
471 } else {
472 self.replace(rhs.as_str(), "").into()
473 }
474 }
475}
476
477impl SubAssign<Self> for ImmutableString {
478 #[inline]
479 fn sub_assign(&mut self, rhs: Self) {
480 if !rhs.is_empty() {
481 if self.is_empty() {
482 self.0 = rhs.0;
483 } else {
484 let rhs: SmartString = self.replace(rhs.as_str(), "").into();
485 self.0 = rhs.into();
486 }
487 }
488 }
489}
490
491impl SubAssign<&Self> for ImmutableString {
492 #[inline]
493 fn sub_assign(&mut self, rhs: &Self) {
494 if !rhs.is_empty() {
495 if self.is_empty() {
496 self.0 = rhs.0.clone();
497 } else {
498 let rhs: SmartString = self.replace(rhs.as_str(), "").into();
499 self.0 = rhs.into();
500 }
501 }
502 }
503}
504
505impl Sub<String> for ImmutableString {
506 type Output = Self;
507
508 #[inline]
509 fn sub(self, rhs: String) -> Self::Output {
510 if rhs.is_empty() {
511 self
512 } else if self.is_empty() {
513 rhs.into()
514 } else {
515 self.replace(&rhs, "").into()
516 }
517 }
518}
519
520impl Sub<String> for &ImmutableString {
521 type Output = ImmutableString;
522
523 #[inline]
524 fn sub(self, rhs: String) -> Self::Output {
525 if rhs.is_empty() {
526 self.clone()
527 } else if self.is_empty() {
528 rhs.into()
529 } else {
530 self.replace(&rhs, "").into()
531 }
532 }
533}
534
535impl SubAssign<String> for ImmutableString {
536 #[inline]
537 fn sub_assign(&mut self, rhs: String) {
538 if !rhs.is_empty() {
539 let rhs: SmartString = self.replace(&rhs, "").into();
540 self.0 = rhs.into();
541 }
542 }
543}
544
545impl Sub<&str> for ImmutableString {
546 type Output = Self;
547
548 #[inline]
549 fn sub(self, rhs: &str) -> Self::Output {
550 if rhs.is_empty() {
551 self
552 } else if self.is_empty() {
553 rhs.into()
554 } else {
555 self.replace(rhs, "").into()
556 }
557 }
558}
559
560impl Sub<&str> for &ImmutableString {
561 type Output = ImmutableString;
562
563 #[inline]
564 fn sub(self, rhs: &str) -> Self::Output {
565 if rhs.is_empty() {
566 self.clone()
567 } else if self.is_empty() {
568 rhs.into()
569 } else {
570 self.replace(rhs, "").into()
571 }
572 }
573}
574
575impl SubAssign<&str> for ImmutableString {
576 #[inline]
577 fn sub_assign(&mut self, rhs: &str) {
578 if !rhs.is_empty() {
579 let rhs: SmartString = self.replace(rhs, "").into();
580 self.0 = rhs.into();
581 }
582 }
583}
584
585impl Sub<char> for ImmutableString {
586 type Output = Self;
587
588 #[inline(always)]
589 fn sub(self, rhs: char) -> Self::Output {
590 self.replace(rhs, "").into()
591 }
592}
593
594impl Sub<char> for &ImmutableString {
595 type Output = ImmutableString;
596
597 #[inline(always)]
598 fn sub(self, rhs: char) -> Self::Output {
599 self.replace(rhs, "").into()
600 }
601}
602
603impl SubAssign<char> for ImmutableString {
604 #[inline]
605 fn sub_assign(&mut self, rhs: char) {
606 let rhs: SmartString = self.replace(rhs, "").into();
607 self.0 = rhs.into();
608 }
609}
610
611impl<S: AsRef<str> + ?Sized> PartialEq<S> for ImmutableString {
612 #[inline(always)]
613 fn eq(&self, other: &S) -> bool {
614 self.as_str().eq(other.as_ref())
615 }
616}
617
618impl PartialEq<str> for &ImmutableString {
619 #[inline(always)]
620 fn eq(&self, other: &str) -> bool {
621 self.as_str().eq(other)
622 }
623}
624
625impl PartialEq<String> for &ImmutableString {
626 #[inline(always)]
627 fn eq(&self, other: &String) -> bool {
628 self.as_str().eq(other.as_str())
629 }
630}
631
632impl PartialEq<ImmutableString> for str {
633 #[inline(always)]
634 fn eq(&self, other: &ImmutableString) -> bool {
635 self.eq(other.as_str())
636 }
637}
638
639impl PartialEq<ImmutableString> for &str {
640 #[inline(always)]
641 fn eq(&self, other: &ImmutableString) -> bool {
642 (*self).eq(other.as_str())
643 }
644}
645
646impl PartialEq<ImmutableString> for String {
647 #[inline(always)]
648 fn eq(&self, other: &ImmutableString) -> bool {
649 self.as_str().eq(other.as_str())
650 }
651}
652
653impl PartialEq<&ImmutableString> for String {
654 #[inline(always)]
655 fn eq(&self, other: &&ImmutableString) -> bool {
656 self.as_str().eq(other.as_str())
657 }
658}
659
660impl PartialEq<ImmutableString> for &String {
661 #[inline(always)]
662 fn eq(&self, other: &ImmutableString) -> bool {
663 self.as_str().eq(other.as_str())
664 }
665}
666
667impl<S: AsRef<str> + ?Sized> PartialOrd<S> for ImmutableString {
668 fn partial_cmp(&self, other: &S) -> Option<Ordering> {
669 self.as_str().partial_cmp(other.as_ref())
670 }
671}
672
673impl PartialOrd<str> for &ImmutableString {
674 fn partial_cmp(&self, other: &str) -> Option<Ordering> {
675 self.as_str().partial_cmp(other)
676 }
677}
678
679impl PartialOrd<String> for &ImmutableString {
680 fn partial_cmp(&self, other: &String) -> Option<Ordering> {
681 self.as_str().partial_cmp(other.as_str())
682 }
683}
684
685impl PartialOrd<ImmutableString> for str {
686 #[inline(always)]
687 fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> {
688 self.partial_cmp(other.as_str())
689 }
690}
691
692impl PartialOrd<ImmutableString> for &str {
693 #[inline(always)]
694 fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> {
695 (*self).partial_cmp(other.as_str())
696 }
697}
698
699impl PartialOrd<ImmutableString> for String {
700 #[inline(always)]
701 fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> {
702 self.as_str().partial_cmp(other.as_str())
703 }
704}
705
706impl PartialOrd<&ImmutableString> for String {
707 #[inline(always)]
708 fn partial_cmp(&self, other: &&ImmutableString) -> Option<Ordering> {
709 self.as_str().partial_cmp(other.as_str())
710 }
711}
712
713impl PartialOrd<ImmutableString> for &String {
714 #[inline(always)]
715 fn partial_cmp(&self, other: &ImmutableString) -> Option<Ordering> {
716 self.as_str().partial_cmp(other.as_str())
717 }
718}
719
720impl ImmutableString {
721 #[inline(always)]
723 #[must_use]
724 pub fn new() -> Self {
725 Self(SmartString::new_const().into())
726 }
727 #[inline(always)]
729 #[must_use]
730 pub fn as_str(&self) -> &str {
731 self.0.as_str()
732 }
733 #[inline(always)]
735 #[must_use]
736 pub fn strong_count(&self) -> usize {
737 Shared::strong_count(&self.0)
738 }
739 #[inline]
743 #[must_use]
744 pub fn into_owned(mut self) -> String {
745 let _ = self.make_mut(); shared_take(self.0).into() }
748 #[inline(always)]
753 #[must_use]
754 pub fn make_mut(&mut self) -> &mut SmartString {
755 shared_make_mut(&mut self.0)
756 }
757 #[inline(always)]
760 pub fn get_mut(&mut self) -> Option<&mut SmartString> {
761 shared_get_mut(&mut self.0)
762 }
763 #[inline(always)]
783 #[must_use]
784 pub fn ptr_eq(&self, other: &Self) -> bool {
785 Shared::ptr_eq(&self.0, &other.0)
786 }
787}