1use std::borrow::{Borrow, BorrowMut, Cow};
2use std::collections::{Bound, TryReserveError};
3use std::convert::Infallible;
4use std::fmt::{Debug, Display, Formatter, Write};
5use std::hash::{Hash, Hasher};
6use std::iter::FusedIterator;
7use std::ops::{
8 Add, AddAssign, Deref, DerefMut, Index, IndexMut, Range, RangeBounds, RangeFrom, RangeFull,
9 RangeInclusive, RangeTo, RangeToInclusive,
10};
11use std::rc::Rc;
12use std::str::FromStr;
13use std::sync::Arc;
14use std::{ptr, slice};
15
16use crate::validations::{
17 run_utf8_full_validation_from_semi, run_utf8_semi_validation, to_range_checked,
18};
19use crate::{Chars, FromUtf8Error, JavaCodePoint, JavaStr, Utf8Error};
20
21#[derive(Default, PartialEq, PartialOrd, Eq, Ord)]
22pub struct JavaString {
23 vec: Vec<u8>,
24}
25
26impl JavaString {
27 #[inline]
28 #[must_use]
29 pub const fn new() -> JavaString {
30 JavaString { vec: Vec::new() }
31 }
32
33 #[inline]
34 #[must_use]
35 pub fn with_capacity(capacity: usize) -> JavaString {
36 JavaString {
37 vec: Vec::with_capacity(capacity),
38 }
39 }
40
41 #[inline]
44 pub fn from_full_utf8(vec: Vec<u8>) -> Result<JavaString, FromUtf8Error> {
45 match std::str::from_utf8(&vec) {
46 Ok(..) => Ok(JavaString { vec }),
47 Err(e) => Err(FromUtf8Error {
48 bytes: vec,
49 error: e.into(),
50 }),
51 }
52 }
53
54 pub fn from_semi_utf8(vec: Vec<u8>) -> Result<JavaString, FromUtf8Error> {
75 match run_utf8_semi_validation(&vec) {
76 Ok(..) => Ok(JavaString { vec }),
77 Err(err) => Err(FromUtf8Error {
78 bytes: vec,
79 error: err,
80 }),
81 }
82 }
83
84 #[must_use]
102 pub fn from_semi_utf8_lossy(v: &[u8]) -> Cow<'_, JavaStr> {
103 const REPLACEMENT: &str = "\u{FFFD}";
104
105 match run_utf8_semi_validation(v) {
106 Ok(()) => unsafe {
107 Cow::Borrowed(JavaStr::from_semi_utf8_unchecked(v))
109 },
110 Err(error) => {
111 let mut result = unsafe {
112 JavaString::from_semi_utf8_unchecked(
114 v.get_unchecked(..error.valid_up_to).to_vec(),
115 )
116 };
117 result.push_str(REPLACEMENT);
118 let mut index = error.valid_up_to + error.error_len.unwrap_or(1) as usize;
119 loop {
120 match run_utf8_semi_validation(&v[index..]) {
121 Ok(()) => {
122 unsafe {
123 result
125 .push_java_str(JavaStr::from_semi_utf8_unchecked(&v[index..]));
126 }
127 return Cow::Owned(result);
128 }
129 Err(error) => {
130 unsafe {
131 result.push_java_str(JavaStr::from_semi_utf8_unchecked(
133 v.get_unchecked(index..index + error.valid_up_to),
134 ));
135 }
136 result.push_str(REPLACEMENT);
137 index += error.valid_up_to + error.error_len.unwrap_or(1) as usize;
138 }
139 }
140 }
141 }
142 }
143 }
144
145 #[inline]
150 #[must_use]
151 pub unsafe fn from_semi_utf8_unchecked(bytes: Vec<u8>) -> JavaString {
152 JavaString { vec: bytes }
153 }
154
155 #[inline]
157 #[must_use]
158 pub fn into_bytes(self) -> Vec<u8> {
159 self.vec
160 }
161
162 #[inline]
164 #[must_use]
165 pub fn as_java_str(&self) -> &JavaStr {
166 unsafe {
167 JavaStr::from_semi_utf8_unchecked(&self.vec)
169 }
170 }
171
172 #[inline]
174 #[must_use]
175 pub fn as_mut_java_str(&mut self) -> &mut JavaStr {
176 unsafe {
177 JavaStr::from_semi_utf8_unchecked_mut(&mut self.vec)
179 }
180 }
181
182 pub fn into_string(self) -> Result<String, Utf8Error> {
202 run_utf8_full_validation_from_semi(self.as_bytes()).map(|_| unsafe {
203 self.into_string_unchecked()
205 })
206 }
207
208 #[inline]
213 #[must_use]
214 pub unsafe fn into_string_unchecked(self) -> String {
215 String::from_utf8_unchecked(self.vec)
217 }
218
219 #[inline]
221 pub fn push_java_str(&mut self, string: &JavaStr) {
222 self.vec.extend_from_slice(string.as_bytes())
223 }
224
225 #[inline]
227 pub fn push_str(&mut self, string: &str) {
228 self.vec.extend_from_slice(string.as_bytes())
229 }
230
231 #[inline]
233 #[must_use]
234 pub fn capacity(&self) -> usize {
235 self.vec.capacity()
236 }
237
238 #[inline]
240 pub fn reserve(&mut self, additional: usize) {
241 self.vec.reserve(additional)
242 }
243
244 #[inline]
246 pub fn reserve_exact(&mut self, additional: usize) {
247 self.vec.reserve_exact(additional)
248 }
249
250 #[inline]
252 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
253 self.vec.try_reserve(additional)
254 }
255
256 #[inline]
258 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
259 self.vec.try_reserve_exact(additional)
260 }
261
262 #[inline]
264 pub fn shrink_to_fit(&mut self) {
265 self.vec.shrink_to_fit()
266 }
267
268 #[inline]
270 pub fn shrink_to(&mut self, min_capacity: usize) {
271 self.vec.shrink_to(min_capacity)
272 }
273
274 #[inline]
276 pub fn push(&mut self, ch: char) {
277 match ch.len_utf8() {
278 1 => self.vec.push(ch as u8),
279 _ => self
280 .vec
281 .extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
282 }
283 }
284
285 #[inline]
287 pub fn push_java(&mut self, ch: JavaCodePoint) {
288 match ch.len_utf8() {
289 1 => self.vec.push(ch.as_u32() as u8),
290 _ => self.vec.extend_from_slice(ch.encode_semi_utf8(&mut [0; 4])),
291 }
292 }
293
294 #[inline]
296 #[must_use]
297 pub fn as_bytes(&self) -> &[u8] {
298 &self.vec
299 }
300
301 #[inline]
303 pub fn truncate(&mut self, new_len: usize) {
304 if new_len <= self.len() {
305 assert!(self.is_char_boundary(new_len));
306 self.vec.truncate(new_len)
307 }
308 }
309
310 #[inline]
326 pub fn pop(&mut self) -> Option<JavaCodePoint> {
327 let ch = self.chars().next_back()?;
328 let newlen = self.len() - ch.len_utf8();
329 unsafe {
330 self.vec.set_len(newlen);
331 }
332 Some(ch)
333 }
334
335 #[inline]
359 pub fn remove(&mut self, idx: usize) -> JavaCodePoint {
360 let ch = match self[idx..].chars().next() {
361 Some(ch) => ch,
362 None => panic!("cannot remove a char from the end of a string"),
363 };
364
365 let next = idx + ch.len_utf8();
366 let len = self.len();
367 unsafe {
368 ptr::copy(
369 self.vec.as_ptr().add(next),
370 self.vec.as_mut_ptr().add(idx),
371 len - next,
372 );
373 self.vec.set_len(len - (next - idx));
374 }
375 ch
376 }
377
378 #[inline]
390 pub fn retain<F>(&mut self, mut f: F)
391 where
392 F: FnMut(JavaCodePoint) -> bool,
393 {
394 struct SetLenOnDrop<'a> {
395 s: &'a mut JavaString,
396 idx: usize,
397 del_bytes: usize,
398 }
399
400 impl<'a> Drop for SetLenOnDrop<'a> {
401 #[inline]
402 fn drop(&mut self) {
403 let new_len = self.idx - self.del_bytes;
404 debug_assert!(new_len <= self.s.len());
405 unsafe { self.s.vec.set_len(new_len) };
406 }
407 }
408
409 let len = self.len();
410 let mut guard = SetLenOnDrop {
411 s: self,
412 idx: 0,
413 del_bytes: 0,
414 };
415
416 while guard.idx < len {
417 let ch = unsafe {
422 guard
423 .s
424 .get_unchecked(guard.idx..len)
425 .chars()
426 .next()
427 .unwrap_unchecked()
428 };
429 let ch_len = ch.len_utf8();
430
431 if !f(ch) {
432 guard.del_bytes += ch_len;
433 } else if guard.del_bytes > 0 {
434 ch.encode_semi_utf8(unsafe {
441 slice::from_raw_parts_mut(
442 guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes),
443 ch.len_utf8(),
444 )
445 });
446 }
447
448 guard.idx += ch_len;
450 }
451
452 drop(guard);
453 }
454
455 #[inline]
466 pub fn insert(&mut self, idx: usize, ch: char) {
467 assert!(self.is_char_boundary(idx));
468 let mut bits = [0; 4];
469 let bits = ch.encode_utf8(&mut bits).as_bytes();
470
471 unsafe {
472 self.insert_bytes(idx, bits);
473 }
474 }
475
476 #[inline]
478 pub fn insert_java(&mut self, idx: usize, ch: JavaCodePoint) {
479 assert!(self.is_char_boundary(idx));
480 let mut bits = [0; 4];
481 let bits = ch.encode_semi_utf8(&mut bits);
482
483 unsafe {
484 self.insert_bytes(idx, bits);
485 }
486 }
487
488 #[inline]
489 unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
490 let len = self.len();
491 let amt = bytes.len();
492 self.vec.reserve(amt);
493
494 unsafe {
495 ptr::copy(
496 self.vec.as_ptr().add(idx),
497 self.vec.as_mut_ptr().add(idx + amt),
498 len - idx,
499 );
500 ptr::copy_nonoverlapping(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
501 self.vec.set_len(len + amt);
502 }
503 }
504
505 #[inline]
514 pub fn insert_str(&mut self, idx: usize, string: &str) {
515 assert!(self.is_char_boundary(idx));
516
517 unsafe {
518 self.insert_bytes(idx, string.as_bytes());
519 }
520 }
521
522 pub fn insert_java_str(&mut self, idx: usize, string: &JavaStr) {
524 assert!(self.is_char_boundary(idx));
525
526 unsafe {
527 self.insert_bytes(idx, string.as_bytes());
528 }
529 }
530
531 #[inline]
538 pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
539 &mut self.vec
540 }
541
542 #[inline]
544 #[must_use]
545 pub fn len(&self) -> usize {
546 self.vec.len()
547 }
548
549 #[inline]
551 #[must_use]
552 pub fn is_empty(&self) -> bool {
553 self.len() == 0
554 }
555
556 #[inline]
572 #[must_use]
573 pub fn split_off(&mut self, at: usize) -> JavaString {
574 assert!(self.is_char_boundary(at));
575 let other = self.vec.split_off(at);
576 unsafe { JavaString::from_semi_utf8_unchecked(other) }
577 }
578
579 #[inline]
581 pub fn clear(&mut self) {
582 self.vec.clear();
583 }
584
585 #[inline]
603 pub fn drain<R>(&mut self, range: R) -> Drain<'_>
604 where
605 R: RangeBounds<usize>,
606 {
607 let Range { start, end } = to_range_checked(range, ..self.len());
609 assert!(self.is_char_boundary(start));
610 assert!(self.is_char_boundary(end));
611
612 let self_ptr = self as *mut _;
615 let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
618
619 Drain {
620 start,
621 end,
622 iter: chars_iter,
623 string: self_ptr,
624 }
625 }
626
627 pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
646 where
647 R: RangeBounds<usize>,
648 {
649 self.replace_range_java(range, JavaStr::from_str(replace_with))
650 }
651
652 pub fn replace_range_java<R>(&mut self, range: R, replace_with: &JavaStr)
654 where
655 R: RangeBounds<usize>,
656 {
657 let start = range.start_bound();
658 match start {
659 Bound::Included(&n) => assert!(self.is_char_boundary(n)),
660 Bound::Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
661 Bound::Unbounded => {}
662 };
663 let end = range.end_bound();
664 match end {
665 Bound::Included(&n) => assert!(self.is_char_boundary(n + 1)),
666 Bound::Excluded(&n) => assert!(self.is_char_boundary(n)),
667 Bound::Unbounded => {}
668 };
669
670 unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
671 }
672
673 #[inline]
675 #[must_use]
676 pub fn into_boxed_str(self) -> Box<JavaStr> {
677 let slice = self.vec.into_boxed_slice();
678 unsafe { JavaStr::from_boxed_semi_utf8_unchecked(slice) }
679 }
680
681 #[inline]
683 pub fn leak<'a>(self) -> &'a mut JavaStr {
684 let slice = self.vec.leak();
685 unsafe { JavaStr::from_semi_utf8_unchecked_mut(slice) }
686 }
687}
688
689impl Add<&str> for JavaString {
690 type Output = JavaString;
691
692 #[inline]
693 fn add(mut self, rhs: &str) -> Self::Output {
694 self.push_str(rhs);
695 self
696 }
697}
698
699impl Add<&JavaStr> for JavaString {
700 type Output = JavaString;
701
702 #[inline]
703 fn add(mut self, rhs: &JavaStr) -> Self::Output {
704 self.push_java_str(rhs);
705 self
706 }
707}
708
709impl AddAssign<&str> for JavaString {
710 #[inline]
711 fn add_assign(&mut self, rhs: &str) {
712 self.push_str(rhs);
713 }
714}
715
716impl AddAssign<&JavaStr> for JavaString {
717 #[inline]
718 fn add_assign(&mut self, rhs: &JavaStr) {
719 self.push_java_str(rhs);
720 }
721}
722
723impl AsMut<JavaStr> for JavaString {
724 #[inline]
725 fn as_mut(&mut self) -> &mut JavaStr {
726 self.as_mut_java_str()
727 }
728}
729
730impl AsRef<[u8]> for JavaString {
731 #[inline]
732 fn as_ref(&self) -> &[u8] {
733 self.as_bytes()
734 }
735}
736
737impl AsRef<JavaStr> for JavaString {
738 #[inline]
739 fn as_ref(&self) -> &JavaStr {
740 self.as_java_str()
741 }
742}
743
744impl Borrow<JavaStr> for JavaString {
745 #[inline]
746 fn borrow(&self) -> &JavaStr {
747 self.as_java_str()
748 }
749}
750
751impl BorrowMut<JavaStr> for JavaString {
752 #[inline]
753 fn borrow_mut(&mut self) -> &mut JavaStr {
754 self.as_mut_java_str()
755 }
756}
757
758impl Clone for JavaString {
759 #[inline]
760 fn clone(&self) -> Self {
761 JavaString {
762 vec: self.vec.clone(),
763 }
764 }
765
766 #[inline]
767 fn clone_from(&mut self, source: &Self) {
768 self.vec.clone_from(&source.vec)
769 }
770}
771
772impl Debug for JavaString {
773 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
774 Debug::fmt(&**self, f)
775 }
776}
777
778impl Deref for JavaString {
779 type Target = JavaStr;
780
781 #[inline]
782 fn deref(&self) -> &Self::Target {
783 self.as_java_str()
784 }
785}
786
787impl DerefMut for JavaString {
788 #[inline]
789 fn deref_mut(&mut self) -> &mut Self::Target {
790 self.as_mut_java_str()
791 }
792}
793
794impl Display for JavaString {
795 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
796 Display::fmt(&**self, f)
797 }
798}
799
800impl Extend<char> for JavaString {
801 fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
802 let iterator = iter.into_iter();
803 let (lower_bound, _) = iterator.size_hint();
804 self.reserve(lower_bound);
805 iterator.for_each(move |c| self.push(c));
806 }
807}
808
809impl Extend<JavaCodePoint> for JavaString {
810 fn extend<T: IntoIterator<Item = JavaCodePoint>>(&mut self, iter: T) {
811 let iterator = iter.into_iter();
812 let (lower_bound, _) = iterator.size_hint();
813 self.reserve(lower_bound);
814 iterator.for_each(move |c| self.push_java(c));
815 }
816}
817
818impl Extend<String> for JavaString {
819 fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
820 iter.into_iter().for_each(move |s| self.push_str(&s));
821 }
822}
823
824impl Extend<JavaString> for JavaString {
825 fn extend<T: IntoIterator<Item = JavaString>>(&mut self, iter: T) {
826 iter.into_iter().for_each(move |s| self.push_java_str(&s));
827 }
828}
829
830impl<'a> Extend<&'a char> for JavaString {
831 fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
832 self.extend(iter.into_iter().cloned())
833 }
834}
835
836impl<'a> Extend<&'a JavaCodePoint> for JavaString {
837 fn extend<T: IntoIterator<Item = &'a JavaCodePoint>>(&mut self, iter: T) {
838 self.extend(iter.into_iter().cloned())
839 }
840}
841
842impl<'a> Extend<&'a str> for JavaString {
843 fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
844 iter.into_iter().for_each(move |s| self.push_str(s));
845 }
846}
847
848impl<'a> Extend<&'a JavaStr> for JavaString {
849 fn extend<T: IntoIterator<Item = &'a JavaStr>>(&mut self, iter: T) {
850 iter.into_iter().for_each(move |s| self.push_java_str(s));
851 }
852}
853
854impl Extend<Box<str>> for JavaString {
855 fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
856 iter.into_iter().for_each(move |s| self.push_str(&s));
857 }
858}
859
860impl Extend<Box<JavaStr>> for JavaString {
861 fn extend<T: IntoIterator<Item = Box<JavaStr>>>(&mut self, iter: T) {
862 iter.into_iter().for_each(move |s| self.push_java_str(&s));
863 }
864}
865
866impl<'a> Extend<Cow<'a, str>> for JavaString {
867 fn extend<T: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: T) {
868 iter.into_iter().for_each(move |s| self.push_str(&s));
869 }
870}
871
872impl<'a> Extend<Cow<'a, JavaStr>> for JavaString {
873 fn extend<T: IntoIterator<Item = Cow<'a, JavaStr>>>(&mut self, iter: T) {
874 iter.into_iter().for_each(move |s| self.push_java_str(&s));
875 }
876}
877
878impl From<String> for JavaString {
879 #[inline]
880 fn from(value: String) -> Self {
881 unsafe {
882 JavaString::from_semi_utf8_unchecked(value.into_bytes())
884 }
885 }
886}
887
888impl From<&String> for JavaString {
889 #[inline]
890 fn from(value: &String) -> Self {
891 Self::from(value.clone())
892 }
893}
894
895impl From<&JavaString> for JavaString {
896 #[inline]
897 fn from(value: &JavaString) -> Self {
898 value.clone()
899 }
900}
901
902impl From<&mut str> for JavaString {
903 #[inline]
904 fn from(value: &mut str) -> Self {
905 Self::from(&*value)
906 }
907}
908
909impl From<&str> for JavaString {
910 #[inline]
911 fn from(value: &str) -> Self {
912 Self::from(value.to_owned())
913 }
914}
915
916impl From<&mut JavaStr> for JavaString {
917 #[inline]
918 fn from(value: &mut JavaStr) -> Self {
919 Self::from(&*value)
920 }
921}
922
923impl From<&JavaStr> for JavaString {
924 #[inline]
925 fn from(value: &JavaStr) -> Self {
926 value.to_owned()
927 }
928}
929
930impl From<Box<str>> for JavaString {
931 #[inline]
932 fn from(value: Box<str>) -> Self {
933 Self::from(value.into_string())
934 }
935}
936
937impl From<Box<JavaStr>> for JavaString {
938 #[inline]
939 fn from(value: Box<JavaStr>) -> Self {
940 value.into_string()
941 }
942}
943
944impl<'a> From<Cow<'a, str>> for JavaString {
945 #[inline]
946 fn from(value: Cow<'a, str>) -> Self {
947 Self::from(value.into_owned())
948 }
949}
950
951impl<'a> From<Cow<'a, JavaStr>> for JavaString {
952 #[inline]
953 fn from(value: Cow<'a, JavaStr>) -> Self {
954 value.into_owned()
955 }
956}
957
958impl From<JavaString> for Arc<JavaStr> {
959 #[inline]
960 fn from(value: JavaString) -> Self {
961 Arc::from(&value[..])
962 }
963}
964
965impl<'a> From<JavaString> for Cow<'a, JavaStr> {
966 #[inline]
967 fn from(value: JavaString) -> Self {
968 Cow::Owned(value)
969 }
970}
971
972impl From<JavaString> for Rc<JavaStr> {
973 #[inline]
974 fn from(value: JavaString) -> Self {
975 Rc::from(&value[..])
976 }
977}
978
979impl From<JavaString> for Vec<u8> {
980 #[inline]
981 fn from(value: JavaString) -> Self {
982 value.into_bytes()
983 }
984}
985
986impl From<char> for JavaString {
987 #[inline]
988 fn from(value: char) -> Self {
989 Self::from(value.encode_utf8(&mut [0; 4]))
990 }
991}
992
993impl From<JavaCodePoint> for JavaString {
994 #[inline]
995 fn from(value: JavaCodePoint) -> Self {
996 unsafe {
997 JavaString::from_semi_utf8_unchecked(value.encode_semi_utf8(&mut [0; 4]).to_vec())
999 }
1000 }
1001}
1002
1003impl FromIterator<char> for JavaString {
1004 #[inline]
1005 fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
1006 let mut buf = JavaString::new();
1007 buf.extend(iter);
1008 buf
1009 }
1010}
1011
1012impl<'a> FromIterator<&'a char> for JavaString {
1013 #[inline]
1014 fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
1015 let mut buf = JavaString::new();
1016 buf.extend(iter);
1017 buf
1018 }
1019}
1020
1021impl FromIterator<JavaCodePoint> for JavaString {
1022 #[inline]
1023 fn from_iter<T: IntoIterator<Item = JavaCodePoint>>(iter: T) -> Self {
1024 let mut buf = JavaString::new();
1025 buf.extend(iter);
1026 buf
1027 }
1028}
1029
1030impl<'a> FromIterator<&'a JavaCodePoint> for JavaString {
1031 #[inline]
1032 fn from_iter<T: IntoIterator<Item = &'a JavaCodePoint>>(iter: T) -> Self {
1033 let mut buf = JavaString::new();
1034 buf.extend(iter);
1035 buf
1036 }
1037}
1038
1039impl<'a> FromIterator<&'a str> for JavaString {
1040 #[inline]
1041 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
1042 let mut buf = JavaString::new();
1043 buf.extend(iter);
1044 buf
1045 }
1046}
1047
1048impl FromIterator<String> for JavaString {
1049 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
1050 let mut iterator = iter.into_iter();
1051
1052 match iterator.next() {
1053 None => JavaString::new(),
1054 Some(buf) => {
1055 let mut buf = JavaString::from(buf);
1056 buf.extend(iterator);
1057 buf
1058 }
1059 }
1060 }
1061}
1062
1063impl FromIterator<JavaString> for JavaString {
1064 fn from_iter<T: IntoIterator<Item = JavaString>>(iter: T) -> Self {
1065 let mut iterator = iter.into_iter();
1066
1067 match iterator.next() {
1068 None => JavaString::new(),
1069 Some(mut buf) => {
1070 buf.extend(iterator);
1071 buf
1072 }
1073 }
1074 }
1075}
1076
1077impl FromIterator<Box<str>> for JavaString {
1078 #[inline]
1079 fn from_iter<T: IntoIterator<Item = Box<str>>>(iter: T) -> Self {
1080 let mut buf = JavaString::new();
1081 buf.extend(iter);
1082 buf
1083 }
1084}
1085
1086impl FromIterator<Box<JavaStr>> for JavaString {
1087 #[inline]
1088 fn from_iter<T: IntoIterator<Item = Box<JavaStr>>>(iter: T) -> Self {
1089 let mut buf = JavaString::new();
1090 buf.extend(iter);
1091 buf
1092 }
1093}
1094
1095impl<'a> FromIterator<Cow<'a, str>> for JavaString {
1096 #[inline]
1097 fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
1098 let mut buf = JavaString::new();
1099 buf.extend(iter);
1100 buf
1101 }
1102}
1103
1104impl<'a> FromIterator<Cow<'a, JavaStr>> for JavaString {
1105 #[inline]
1106 fn from_iter<T: IntoIterator<Item = Cow<'a, JavaStr>>>(iter: T) -> Self {
1107 let mut buf = JavaString::new();
1108 buf.extend(iter);
1109 buf
1110 }
1111}
1112
1113impl FromStr for JavaString {
1114 type Err = Infallible;
1115
1116 #[inline]
1117 fn from_str(s: &str) -> Result<Self, Self::Err> {
1118 Ok(Self::from(s))
1119 }
1120}
1121
1122impl Hash for JavaString {
1123 #[inline]
1124 fn hash<H: Hasher>(&self, state: &mut H) {
1125 (**self).hash(state)
1126 }
1127}
1128
1129impl Index<Range<usize>> for JavaString {
1130 type Output = JavaStr;
1131
1132 #[inline]
1133 fn index(&self, index: Range<usize>) -> &Self::Output {
1134 &self[..][index]
1135 }
1136}
1137
1138impl Index<RangeFrom<usize>> for JavaString {
1139 type Output = JavaStr;
1140
1141 #[inline]
1142 fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
1143 &self[..][index]
1144 }
1145}
1146
1147impl Index<RangeFull> for JavaString {
1148 type Output = JavaStr;
1149
1150 #[inline]
1151 fn index(&self, _index: RangeFull) -> &Self::Output {
1152 self.as_java_str()
1153 }
1154}
1155
1156impl Index<RangeInclusive<usize>> for JavaString {
1157 type Output = JavaStr;
1158
1159 #[inline]
1160 fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
1161 &self[..][index]
1162 }
1163}
1164
1165impl Index<RangeTo<usize>> for JavaString {
1166 type Output = JavaStr;
1167
1168 #[inline]
1169 fn index(&self, index: RangeTo<usize>) -> &Self::Output {
1170 &self[..][index]
1171 }
1172}
1173
1174impl Index<RangeToInclusive<usize>> for JavaString {
1175 type Output = JavaStr;
1176
1177 #[inline]
1178 fn index(&self, index: RangeToInclusive<usize>) -> &Self::Output {
1179 &self[..][index]
1180 }
1181}
1182
1183impl IndexMut<Range<usize>> for JavaString {
1184 #[inline]
1185 fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
1186 &mut self[..][index]
1187 }
1188}
1189
1190impl IndexMut<RangeFrom<usize>> for JavaString {
1191 #[inline]
1192 fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
1193 &mut self[..][index]
1194 }
1195}
1196
1197impl IndexMut<RangeFull> for JavaString {
1198 #[inline]
1199 fn index_mut(&mut self, _index: RangeFull) -> &mut Self::Output {
1200 self.as_mut_java_str()
1201 }
1202}
1203
1204impl IndexMut<RangeInclusive<usize>> for JavaString {
1205 #[inline]
1206 fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
1207 &mut self[..][index]
1208 }
1209}
1210
1211impl IndexMut<RangeTo<usize>> for JavaString {
1212 #[inline]
1213 fn index_mut(&mut self, index: RangeTo<usize>) -> &mut Self::Output {
1214 &mut self[..][index]
1215 }
1216}
1217
1218impl IndexMut<RangeToInclusive<usize>> for JavaString {
1219 #[inline]
1220 fn index_mut(&mut self, index: RangeToInclusive<usize>) -> &mut Self::Output {
1221 &mut self[..][index]
1222 }
1223}
1224
1225impl PartialEq<str> for JavaString {
1226 #[inline]
1227 fn eq(&self, other: &str) -> bool {
1228 self[..] == other
1229 }
1230}
1231
1232impl PartialEq<JavaString> for str {
1233 #[inline]
1234 fn eq(&self, other: &JavaString) -> bool {
1235 self == other[..]
1236 }
1237}
1238
1239impl<'a> PartialEq<&'a str> for JavaString {
1240 #[inline]
1241 fn eq(&self, other: &&'a str) -> bool {
1242 self == *other
1243 }
1244}
1245
1246impl<'a> PartialEq<JavaString> for &'a str {
1247 #[inline]
1248 fn eq(&self, other: &JavaString) -> bool {
1249 *self == other
1250 }
1251}
1252
1253impl PartialEq<String> for JavaString {
1254 #[inline]
1255 fn eq(&self, other: &String) -> bool {
1256 &self[..] == other
1257 }
1258}
1259
1260impl PartialEq<JavaString> for String {
1261 #[inline]
1262 fn eq(&self, other: &JavaString) -> bool {
1263 self == &other[..]
1264 }
1265}
1266
1267impl PartialEq<JavaStr> for JavaString {
1268 #[inline]
1269 fn eq(&self, other: &JavaStr) -> bool {
1270 self[..] == other
1271 }
1272}
1273
1274impl<'a> PartialEq<&'a JavaStr> for JavaString {
1275 #[inline]
1276 fn eq(&self, other: &&'a JavaStr) -> bool {
1277 self == *other
1278 }
1279}
1280
1281impl<'a> PartialEq<Cow<'a, str>> for JavaString {
1282 #[inline]
1283 fn eq(&self, other: &Cow<'a, str>) -> bool {
1284 &self[..] == other
1285 }
1286}
1287
1288impl<'a> PartialEq<JavaString> for Cow<'a, str> {
1289 #[inline]
1290 fn eq(&self, other: &JavaString) -> bool {
1291 self == &other[..]
1292 }
1293}
1294
1295impl<'a> PartialEq<Cow<'a, JavaStr>> for JavaString {
1296 #[inline]
1297 fn eq(&self, other: &Cow<'a, JavaStr>) -> bool {
1298 &self[..] == other
1299 }
1300}
1301
1302impl<'a> PartialEq<JavaString> for Cow<'a, JavaStr> {
1303 #[inline]
1304 fn eq(&self, other: &JavaString) -> bool {
1305 self == &other[..]
1306 }
1307}
1308
1309impl Write for JavaString {
1310 #[inline]
1311 fn write_str(&mut self, s: &str) -> std::fmt::Result {
1312 self.push_str(s);
1313 Ok(())
1314 }
1315
1316 #[inline]
1317 fn write_char(&mut self, c: char) -> std::fmt::Result {
1318 self.push(c);
1319 Ok(())
1320 }
1321}
1322
1323pub struct Drain<'a> {
1324 string: *mut JavaString,
1325 start: usize,
1326 end: usize,
1327 iter: Chars<'a>,
1328}
1329
1330impl Debug for Drain<'_> {
1331 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1332 f.debug_tuple("Drain").field(&self.as_str()).finish()
1333 }
1334}
1335
1336unsafe impl Sync for Drain<'_> {}
1337unsafe impl Send for Drain<'_> {}
1338
1339impl Drop for Drain<'_> {
1340 #[inline]
1341 fn drop(&mut self) {
1342 unsafe {
1343 let self_vec = (*self.string).as_mut_vec();
1346 if self.start <= self.end && self.end <= self_vec.len() {
1347 self_vec.drain(self.start..self.end);
1348 }
1349 }
1350 }
1351}
1352
1353impl AsRef<JavaStr> for Drain<'_> {
1354 #[inline]
1355 fn as_ref(&self) -> &JavaStr {
1356 self.as_str()
1357 }
1358}
1359
1360impl AsRef<[u8]> for Drain<'_> {
1361 #[inline]
1362 fn as_ref(&self) -> &[u8] {
1363 self.as_str().as_bytes()
1364 }
1365}
1366
1367impl Drain<'_> {
1368 #[inline]
1369 #[must_use]
1370 pub fn as_str(&self) -> &JavaStr {
1371 self.iter.as_str()
1372 }
1373}
1374
1375impl Iterator for Drain<'_> {
1376 type Item = JavaCodePoint;
1377
1378 #[inline]
1379 fn next(&mut self) -> Option<JavaCodePoint> {
1380 self.iter.next()
1381 }
1382
1383 #[inline]
1384 fn size_hint(&self) -> (usize, Option<usize>) {
1385 self.iter.size_hint()
1386 }
1387
1388 #[inline]
1389 fn last(mut self) -> Option<JavaCodePoint> {
1390 self.next_back()
1391 }
1392}
1393
1394impl DoubleEndedIterator for Drain<'_> {
1395 #[inline]
1396 fn next_back(&mut self) -> Option<Self::Item> {
1397 self.iter.next_back()
1398 }
1399}
1400
1401impl FusedIterator for Drain<'_> {}