1use std::{
2 borrow::{Borrow, BorrowMut, Cow},
3 error::Error,
4 ffi::{OsStr, OsString},
5 fmt::Write,
6 hash::{self, Hash},
7 iter::{Extend, FromIterator},
8 net::ToSocketAddrs,
9 ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut, RangeBounds},
10 path::{Path, PathBuf},
11 rc::Rc,
12 slice::SliceIndex,
13 str::{self, FromStr},
14 string::{Drain, ParseError},
15 sync::Arc,
16};
17
18use crate::{
19 intern::{Interned, Muterned},
20 IStr,
21};
22
23#[derive(Debug, Eq, Ord, PartialOrd)]
24enum MowStrInner {
25 I(IStr),
26 M(Option<String>),
27}
28
29type Inner = MowStrInner;
30
31impl PartialEq for MowStrInner {
32 #[inline]
33 fn eq(&self, other: &Self) -> bool {
34 match self {
35 Self::I(s) => match other {
36 Self::I(o) => s == o,
37 Self::M(o) => o.as_ref().unwrap() == s.deref(),
38 },
39 Self::M(s) => match other {
40 Self::I(o) => s.as_ref().unwrap() == o.deref(),
41 Self::M(o) => s == o,
42 },
43 }
44 }
45}
46
47#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
69pub struct MowStr(Inner);
70
71impl MowStr {
72 #[inline]
80 pub fn new(s: impl AsRef<str>) -> Self {
81 Self(Inner::I(IStr::new(s)))
82 }
83
84 #[inline]
93 pub fn new_mut(s: impl Into<String>) -> Self {
94 Self(Inner::M(Some(s.into())))
95 }
96
97 #[inline]
106 pub fn mut_empty() -> Self {
107 Self::new_mut(String::new())
108 }
109
110 #[inline]
112 pub fn mut_with_capacity(capacity: usize) -> Self {
113 Self::new_mut(String::with_capacity(capacity))
114 }
115
116 #[inline]
118 pub fn from_string(s: String) -> Self {
119 Self(Inner::I(IStr::from_string(s)))
120 }
121
122 #[inline]
124 pub fn from_string_mut(s: String) -> Self {
125 Self(Inner::M(Some(s)))
126 }
127
128 #[inline]
130 pub fn from_boxed(s: Box<str>) -> Self {
131 Self(Inner::I(IStr::from_boxed(s)))
132 }
133
134 #[inline]
136 pub fn from_arc(s: Arc<str>) -> Self {
137 Self(Inner::I(IStr::from_arc(s)))
138 }
139
140 #[inline]
142 pub fn from_rc(s: Rc<str>) -> Self {
143 Self(Inner::I(IStr::from_rc(s)))
144 }
145
146 #[inline]
148 pub fn from_istr(s: IStr) -> Self {
149 Self(Inner::I(s))
150 }
151
152 #[inline]
154 pub fn from_to_arc<S: AsRef<str>>(s: S, to_arc: impl FnOnce(S) -> Arc<str>) -> Self {
155 Self(Inner::I(IStr::from_to_arc(s, to_arc)))
156 }
157}
158
159impl MowStr {
160 #[inline]
163 pub fn intern(&mut self) {
164 let s = match &mut self.0 {
165 Inner::I(_) => return,
166 MowStrInner::M(s) => s.take().unwrap(),
167 };
168 *self = Self::from_string(s);
169 }
170
171 #[inline]
174 pub fn to_mut(&mut self) {
175 let s = match &mut self.0 {
176 Inner::I(v) => v.to_string(),
177 Inner::M(_) => return,
178 };
179 *self = Self::from_string_mut(s);
180 }
181
182 #[inline]
184 pub fn mutdown(&mut self) -> &mut String {
185 self.to_mut();
186 match &mut self.0 {
187 Inner::I(_) => panic!("never"),
188 Inner::M(v) => v.as_mut().unwrap(),
189 }
190 }
191
192 #[inline]
194 pub fn to_mut_by(&mut self, f: impl FnOnce(&mut IStr) -> String) {
195 let s = match &mut self.0 {
196 Inner::I(v) => f(v),
197 Inner::M(_) => return,
198 };
199 *self = Self::from_string_mut(s);
200 }
201
202 pub fn swap_mut(&mut self, s: String) -> Option<String> {
205 let r = match &mut self.0 {
206 Inner::I(_) => None,
207 MowStrInner::M(s) => Some(s.take().unwrap()),
208 };
209 *self = Self::from_string_mut(s);
210 r
211 }
212
213 pub fn try_swap_mut(&mut self, s: String) -> Option<String> {
217 let r = match &mut self.0 {
218 Inner::I(_) => None,
219 MowStrInner::M(s) => Some(s.take().unwrap()),
220 };
221 if r.is_some() {
222 *self = Self::from_string_mut(s);
223 }
224 r
225 }
226
227 #[inline]
229 pub fn is_interned(&self) -> bool {
230 matches!(&self.0, Inner::I(_))
231 }
232
233 #[inline]
235 pub fn is_mutable(&self) -> bool {
236 matches!(&self.0, Inner::M(_))
237 }
238
239 #[inline]
241 pub fn try_istr(&self) -> Option<&IStr> {
242 match &self.0 {
243 Inner::I(v) => Some(v),
244 Inner::M(_) => None,
245 }
246 }
247
248 #[inline]
250 pub fn try_string(&self) -> Option<&String> {
251 match &self.0 {
252 Inner::I(_) => None,
253 Inner::M(v) => Some(v.as_ref().unwrap()),
254 }
255 }
256
257 #[inline]
259 pub fn into_istr(&self) -> IStr {
260 match &self.0 {
261 Inner::I(v) => v.clone(),
262 Inner::M(s) => s.as_ref().unwrap().into(),
263 }
264 }
265}
266
267impl MowStr {
268 #[inline]
270 pub fn ref_str(&self) -> &str {
271 self.deref()
272 }
273
274 #[inline]
276 pub fn mut_str(&mut self) -> &mut str {
277 self.as_mut()
278 }
279
280 #[inline]
282 pub fn mut_string(&mut self) -> &mut String {
283 self.as_mut()
284 }
285
286 #[inline]
288 pub fn as_str(&self) -> &str {
289 self.deref()
290 }
291
292 #[inline]
294 pub fn as_mut_str(&mut self) -> &mut str {
295 self.mut_str()
296 }
297
298 #[inline]
300 pub fn as_mut_string(&mut self) -> &mut String {
301 self.mut_string()
302 }
303
304 #[inline]
306 pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
307 self.mutdown().as_mut_vec()
308 }
309
310 #[inline]
312 pub fn into_string(self) -> String {
313 match self.0 {
314 Inner::I(v) => v.to_string(),
315 Inner::M(v) => v.unwrap(),
316 }
317 }
318
319 #[inline]
321 pub fn into_boxed_str(self) -> Box<str> {
322 match self.0 {
323 Inner::I(v) => v.into_boxed_str(),
324 Inner::M(v) => v.unwrap().into_boxed_str(),
325 }
326 }
327}
328
329impl MowStr {
330 #[inline]
332 pub fn push_str(&mut self, string: impl AsRef<str>) {
333 self.mutdown().push_str(string.as_ref())
334 }
335
336 #[inline]
348 pub fn reserve(&mut self, additional: usize) {
349 self.mutdown().reserve(additional)
350 }
351
352 #[inline]
364 pub fn reserve_exact(&mut self, additional: usize) {
365 self.mutdown().reserve_exact(additional)
366 }
367
368 #[inline]
370 pub fn shrink_to_fit(&mut self) {
371 self.mutdown().shrink_to_fit()
372 }
373
374 #[inline]
376 pub fn push(&mut self, ch: char) {
377 self.mutdown().push(ch)
378 }
379
380 #[inline]
392 pub fn truncate(&mut self, new_len: usize) {
393 self.mutdown().truncate(new_len)
394 }
395
396 #[inline]
400 pub fn pop(&mut self) -> Option<char> {
401 self.mutdown().pop()
402 }
403
404 #[inline]
414 pub fn remove(&mut self, idx: usize) -> char {
415 self.mutdown().remove(idx)
416 }
417
418 #[inline]
424 pub fn retain<F: FnMut(char) -> bool>(&mut self, f: F) {
425 self.mutdown().retain(f)
426 }
427
428 #[inline]
438 pub fn insert(&mut self, idx: usize, ch: char) {
439 self.mutdown().insert(idx, ch)
440 }
441
442 #[inline]
452 pub fn insert_str(&mut self, idx: usize, string: &str) {
453 self.mutdown().insert_str(idx, string)
454 }
455
456 #[inline]
469 pub fn split_off(&mut self, at: usize) -> MowStr {
470 Self::from_string_mut(self.mutdown().split_off(at))
471 }
472
473 #[inline]
478 pub fn clear(&mut self) {
479 self.mutdown().clear()
480 }
481
482 #[inline]
493 pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> Drain<'_> {
494 self.mutdown().drain(range)
495 }
496
497 #[inline]
506 pub fn replace_range<R: RangeBounds<usize>>(&mut self, range: R, replace_with: &str) {
507 self.mutdown().replace_range(range, replace_with)
508 }
509}
510
511unsafe impl Interned for MowStr {}
512unsafe impl Muterned for MowStr {}
513
514impl Clone for MowStr {
515 fn clone(&self) -> Self {
516 match &self.0 {
517 Inner::I(v) => Self::from_istr(v.clone()),
518 Inner::M(v) => Self::from_string(v.clone().unwrap()),
519 }
520 }
521}
522
523impl Deref for MowStr {
524 type Target = str;
525
526 #[inline]
527 fn deref(&self) -> &Self::Target {
528 self.as_ref()
529 }
530}
531
532impl DerefMut for MowStr {
533 #[inline]
534 fn deref_mut(&mut self) -> &mut Self::Target {
535 self.as_mut()
536 }
537}
538
539impl FromStr for MowStr {
540 type Err = ParseError;
541
542 #[inline]
543 fn from_str(s: &str) -> Result<Self, Self::Err> {
544 Ok(Self::new(s))
545 }
546}
547
548impl AsRef<str> for MowStr {
549 #[inline]
550 fn as_ref(&self) -> &str {
551 match &self.0 {
552 Inner::I(v) => v.as_ref(),
553 Inner::M(v) => v.as_ref().unwrap(),
554 }
555 }
556}
557
558impl AsMut<str> for MowStr {
559 #[inline]
560 fn as_mut(&mut self) -> &mut str {
561 self.mutdown()
562 }
563}
564
565impl AsMut<String> for MowStr {
566 #[inline]
567 fn as_mut(&mut self) -> &mut String {
568 self.mutdown()
569 }
570}
571
572impl AsRef<[u8]> for MowStr {
573 #[inline]
574 fn as_ref(&self) -> &[u8] {
575 match &self.0 {
576 Inner::I(v) => v.as_ref(),
577 Inner::M(v) => v.as_ref().unwrap().as_ref(),
578 }
579 }
580}
581
582impl AsRef<OsStr> for MowStr {
583 #[inline]
584 fn as_ref(&self) -> &OsStr {
585 match &self.0 {
586 Inner::I(v) => v.as_ref(),
587 Inner::M(v) => v.as_ref().unwrap().as_ref(),
588 }
589 }
590}
591
592impl AsRef<Path> for MowStr {
593 #[inline]
594 fn as_ref(&self) -> &Path {
595 match &self.0 {
596 Inner::I(v) => v.as_ref(),
597 Inner::M(v) => v.as_ref().unwrap().as_ref(),
598 }
599 }
600}
601
602impl<I: SliceIndex<str>> Index<I> for MowStr {
603 type Output = <I as SliceIndex<str>>::Output;
604
605 #[inline]
606 fn index(&self, index: I) -> &Self::Output {
607 self.deref().index(index)
608 }
609}
610
611impl<I: SliceIndex<str>> IndexMut<I> for MowStr {
612 #[inline]
613 fn index_mut(&mut self, index: I) -> &mut Self::Output {
614 self.deref_mut().index_mut(index)
615 }
616}
617
618impl Hash for MowStr {
619 #[inline]
620 fn hash<H: hash::Hasher>(&self, state: &mut H) {
621 self.deref().hash(state)
622 }
623}
624
625impl Borrow<str> for MowStr {
626 #[inline]
627 fn borrow(&self) -> &str {
628 self.deref()
629 }
630}
631
632impl BorrowMut<str> for MowStr {
633 #[inline]
634 fn borrow_mut(&mut self) -> &mut str {
635 self.deref_mut()
636 }
637}
638
639impl<'a> Extend<&'a char> for MowStr {
640 #[inline]
641 fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
642 self.mutdown().extend(iter)
643 }
644}
645
646impl<'a> Extend<&'a str> for MowStr {
647 #[inline]
648 fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
649 self.mutdown().extend(iter)
650 }
651}
652
653impl Extend<Box<str>> for MowStr {
654 #[inline]
655 fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
656 self.mutdown().extend(iter)
657 }
658}
659
660impl<'a> Extend<Cow<'a, str>> for MowStr {
661 #[inline]
662 fn extend<T: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: T) {
663 self.mutdown().extend(iter)
664 }
665}
666
667impl Extend<String> for MowStr {
668 #[inline]
669 fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
670 self.mutdown().extend(iter)
671 }
672}
673
674impl Extend<IStr> for MowStr {
675 #[inline]
676 fn extend<T: IntoIterator<Item = IStr>>(&mut self, iter: T) {
677 let stri = self.mutdown();
678 iter.into_iter().for_each(move |s| stri.push_str(&s))
679 }
680}
681
682impl Extend<MowStr> for MowStr {
683 #[inline]
684 fn extend<T: IntoIterator<Item = MowStr>>(&mut self, iter: T) {
685 let stri = self.mutdown();
686 iter.into_iter().for_each(move |s| stri.push_str(&s))
687 }
688}
689
690impl Add<&str> for MowStr {
691 type Output = MowStr;
692
693 #[inline]
694 fn add(mut self, rhs: &str) -> Self::Output {
695 self.mutdown().push_str(rhs);
696 self
697 }
698}
699
700impl AddAssign<&str> for MowStr {
701 #[inline]
702 fn add_assign(&mut self, rhs: &str) {
703 self.mutdown().push_str(rhs);
704 }
705}
706
707impl From<&String> for MowStr {
708 #[inline]
709 fn from(s: &String) -> Self {
710 Self::new(s)
711 }
712}
713
714impl From<&str> for MowStr {
715 #[inline]
716 fn from(s: &str) -> Self {
717 Self::new(s)
718 }
719}
720
721impl From<&mut str> for MowStr {
722 #[inline]
723 fn from(s: &mut str) -> Self {
724 Self::new(s)
725 }
726}
727
728impl From<String> for MowStr {
729 #[inline]
730 fn from(s: String) -> Self {
731 Self::from_string(s)
732 }
733}
734
735impl From<Box<str>> for MowStr {
736 #[inline]
737 fn from(s: Box<str>) -> Self {
738 Self::from_boxed(s)
739 }
740}
741
742impl From<Arc<str>> for MowStr {
743 #[inline]
744 fn from(s: Arc<str>) -> Self {
745 Self::from_arc(s)
746 }
747}
748
749impl From<Rc<str>> for MowStr {
750 #[inline]
751 fn from(s: Rc<str>) -> Self {
752 Self::from_rc(s)
753 }
754}
755
756impl<'a> From<Cow<'a, str>> for MowStr {
757 #[inline]
758 fn from(s: Cow<'a, str>) -> Self {
759 Self::from_string(s.into_owned())
760 }
761}
762
763impl From<char> for MowStr {
764 #[inline]
765 fn from(c: char) -> Self {
766 let mut tmp = [0; 4];
767 Self::new(c.encode_utf8(&mut tmp))
768 }
769}
770
771impl ToSocketAddrs for MowStr {
772 type Iter = <str as ToSocketAddrs>::Iter;
773
774 #[inline]
775 fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
776 ToSocketAddrs::to_socket_addrs(self.deref())
777 }
778}
779
780impl Write for MowStr {
781 #[inline]
782 fn write_str(&mut self, s: &str) -> std::fmt::Result {
783 self.push_str(s);
784 Ok(())
785 }
786
787 #[inline]
788 fn write_char(&mut self, c: char) -> std::fmt::Result {
789 self.push(c);
790 Ok(())
791 }
792}
793
794impl ToString for MowStr {
795 #[inline]
796 fn to_string(&self) -> String {
797 match &self.0 {
798 Inner::I(v) => v.to_string(),
799 Inner::M(v) => v.clone().unwrap(),
800 }
801 }
802}
803
804impl From<MowStr> for String {
805 #[inline]
806 fn from(v: MowStr) -> Self {
807 v.into_string()
808 }
809}
810
811impl<'a> FromIterator<&'a char> for MowStr {
812 #[inline]
813 fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
814 Self::from_string(String::from_iter(iter))
815 }
816}
817
818impl<'a> FromIterator<&'a str> for MowStr {
819 #[inline]
820 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
821 Self::from_string(String::from_iter(iter))
822 }
823}
824
825impl FromIterator<Box<str>> for MowStr {
826 #[inline]
827 fn from_iter<T: IntoIterator<Item = Box<str>>>(iter: T) -> Self {
828 Self::from_string(String::from_iter(iter))
829 }
830}
831
832impl<'a> FromIterator<Cow<'a, str>> for MowStr {
833 #[inline]
834 fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
835 Self::from_string(String::from_iter(iter))
836 }
837}
838
839impl FromIterator<String> for MowStr {
840 #[inline]
841 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
842 Self::from_string(String::from_iter(iter))
843 }
844}
845
846impl FromIterator<char> for MowStr {
847 #[inline]
848 fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
849 Self::from_string(String::from_iter(iter))
850 }
851}
852
853impl From<MowStr> for Box<str> {
854 #[inline]
855 fn from(v: MowStr) -> Self {
856 match &v.0 {
857 Inner::I(v) => Self::from(v.deref()),
858 Inner::M(v) => Self::from(v.as_deref().unwrap()),
859 }
860 }
861}
862
863impl From<MowStr> for Vec<u8> {
864 #[inline]
865 fn from(v: MowStr) -> Self {
866 match &v.0 {
867 Inner::I(v) => Self::from(v.deref()),
868 Inner::M(v) => Self::from(v.as_deref().unwrap()),
869 }
870 }
871}
872
873impl From<MowStr> for Arc<str> {
874 #[inline]
875 fn from(v: MowStr) -> Self {
876 match &v.0 {
877 Inner::I(v) => Self::from(v.clone()),
878 Inner::M(v) => Self::from(v.clone().unwrap()),
879 }
880 }
881}
882
883impl From<MowStr> for Rc<str> {
884 #[inline]
885 fn from(v: MowStr) -> Self {
886 match &v.0 {
887 Inner::I(v) => Self::from(v.clone()),
888 Inner::M(v) => Self::from(v.clone().unwrap()),
889 }
890 }
891}
892
893impl<'a> From<MowStr> for Cow<'a, str> {
894 #[inline]
895 fn from(v: MowStr) -> Self {
896 Cow::Owned(v.to_string())
897 }
898}
899
900impl<'a> From<&'a MowStr> for Cow<'a, str> {
901 #[inline]
902 fn from(v: &'a MowStr) -> Self {
903 Cow::Borrowed(v.deref())
904 }
905}
906
907impl From<MowStr> for Box<dyn Error> {
908 #[inline]
909 fn from(v: MowStr) -> Self {
910 match &v.0 {
911 Inner::I(v) => Self::from(v.clone()),
912 Inner::M(v) => Self::from(v.clone().unwrap()),
913 }
914 }
915}
916
917impl From<MowStr> for Box<dyn Error + Send + Sync> {
918 #[inline]
919 fn from(v: MowStr) -> Self {
920 match &v.0 {
921 Inner::I(v) => Self::from(v.clone()),
922 Inner::M(v) => Self::from(v.clone().unwrap()),
923 }
924 }
925}
926
927impl From<MowStr> for OsString {
928 #[inline]
929 fn from(v: MowStr) -> Self {
930 match &v.0 {
931 Inner::I(v) => Self::from(v.deref()),
932 Inner::M(v) => Self::from(v.as_ref().unwrap()),
933 }
934 }
935}
936
937impl From<MowStr> for PathBuf {
938 #[inline]
939 fn from(v: MowStr) -> Self {
940 match &v.0 {
941 Inner::I(v) => Self::from(v.deref()),
942 Inner::M(v) => Self::from(v.as_ref().unwrap()),
943 }
944 }
945}
946
947impl From<IStr> for MowStr {
948 #[inline]
949 fn from(v: IStr) -> Self {
950 Self::from_istr(v)
951 }
952}
953
954impl From<MowStr> for IStr {
955 fn from(v: MowStr) -> Self {
956 match v.0 {
957 Inner::I(v) => v,
958 Inner::M(v) => Self::from_string(v.unwrap()),
959 }
960 }
961}
962
963impl PartialEq<str> for MowStr {
964 fn eq(&self, other: &str) -> bool {
965 self.deref() == other
966 }
967}
968
969impl PartialEq<&str> for MowStr {
970 fn eq(&self, other: &&str) -> bool {
971 self.deref() == *other
972 }
973}
974
975impl PartialEq<String> for MowStr {
976 fn eq(&self, other: &String) -> bool {
977 self.deref() == *other
978 }
979}
980
981impl PartialEq<OsStr> for MowStr {
982 fn eq(&self, other: &OsStr) -> bool {
983 self.deref() == other
984 }
985}
986
987impl PartialEq<&OsStr> for MowStr {
988 fn eq(&self, other: &&OsStr) -> bool {
989 self.deref() == *other
990 }
991}
992
993impl PartialEq<OsString> for MowStr {
994 fn eq(&self, other: &OsString) -> bool {
995 self.deref() == *other
996 }
997}
998
999#[cfg(test)]
1000mod tests {
1001 use super::*;
1002
1003 #[test]
1004 fn test_1() {
1005 let s = MowStr::new("asd");
1006 assert_eq!(s, "asd");
1007 }
1008
1009 #[test]
1010 fn test_2() {
1011 let a = MowStr::new("asd");
1012 let b = MowStr::new("asd");
1013 assert_eq!(a, b);
1014 }
1015
1016 #[test]
1017 fn test_3() {
1018 let a = MowStr::new("asd");
1019 let b = MowStr::new("123");
1020 assert_ne!(a, b);
1021 }
1022
1023 #[test]
1024 fn test_mut() {
1025 let mut a = MowStr::new("asd");
1026 assert!(a.is_interned());
1027 a.mutdown();
1028 assert!(a.is_mutable());
1029 }
1030
1031 #[test]
1032 fn test_mut_2() {
1033 let mut a = MowStr::new("asd");
1034 assert!(a.is_interned());
1035 assert_eq!(a, "asd");
1036 a.push_str("123");
1037 assert!(a.is_mutable());
1038 assert_eq!(a, "asd123");
1039 }
1040}