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