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
26#[allow(clippy::multiple_inherent_impl)]
27impl JavaString {
28 #[inline]
29 #[must_use]
30 pub const fn new() -> JavaString {
31 JavaString { vec: Vec::new() }
32 }
33
34 #[inline]
35 #[must_use]
36 pub fn with_capacity(capacity: usize) -> JavaString {
37 JavaString {
38 vec: Vec::with_capacity(capacity),
39 }
40 }
41
42 #[inline]
45 pub fn from_full_utf8(vec: Vec<u8>) -> Result<JavaString, FromUtf8Error> {
46 match std::str::from_utf8(&vec) {
47 Ok(..) => Ok(JavaString { vec }),
48 Err(e) => Err(FromUtf8Error {
49 bytes: vec,
50 error: e.into(),
51 }),
52 }
53 }
54
55 pub fn from_semi_utf8(vec: Vec<u8>) -> Result<JavaString, FromUtf8Error> {
76 match run_utf8_semi_validation(&vec) {
77 Ok(..) => Ok(JavaString { vec }),
78 Err(err) => Err(FromUtf8Error {
79 bytes: vec,
80 error: err,
81 }),
82 }
83 }
84
85 #[must_use]
103 pub fn from_semi_utf8_lossy(v: &[u8]) -> Cow<'_, JavaStr> {
104 const REPLACEMENT: &str = "\u{FFFD}";
105
106 match run_utf8_semi_validation(v) {
107 Ok(()) => unsafe {
108 Cow::Borrowed(JavaStr::from_semi_utf8_unchecked(v))
110 },
111 Err(error) => {
112 let mut result = unsafe {
113 JavaString::from_semi_utf8_unchecked(
115 v.get_unchecked(..error.valid_up_to).to_vec(),
116 )
117 };
118 result.push_str(REPLACEMENT);
119 let mut index = error.valid_up_to + error.error_len.unwrap_or(1) as usize;
120 loop {
121 match run_utf8_semi_validation(&v[index..]) {
122 Ok(()) => {
123 unsafe {
124 result.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 const fn as_java_str(&self) -> &JavaStr {
166 unsafe {
167 JavaStr::from_semi_utf8_unchecked(self.vec.as_slice())
169 }
170 }
171
172 #[inline]
174 #[must_use]
175 pub const fn as_mut_java_str(&mut self) -> &mut JavaStr {
176 unsafe {
177 JavaStr::from_semi_utf8_unchecked_mut(self.vec.as_mut_slice())
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 unsafe {
216 String::from_utf8_unchecked(self.vec)
218 }
219 }
220
221 #[inline]
223 pub fn push_java_str(&mut self, string: &JavaStr) {
224 self.vec.extend_from_slice(string.as_bytes())
225 }
226
227 #[inline]
229 pub fn push_str(&mut self, string: &str) {
230 self.vec.extend_from_slice(string.as_bytes())
231 }
232
233 #[inline]
235 pub fn extend_from_within<R>(&mut self, src: R)
236 where
237 R: RangeBounds<usize>,
238 {
239 let src @ Range { start, end } = to_range_checked(src, ..self.len());
240
241 assert!(self.is_char_boundary(start));
242 assert!(self.is_char_boundary(end));
243
244 self.vec.extend_from_within(src);
245 }
246
247 #[inline]
249 #[must_use]
250 pub const fn capacity(&self) -> usize {
251 self.vec.capacity()
252 }
253
254 #[inline]
256 pub fn reserve(&mut self, additional: usize) {
257 self.vec.reserve(additional)
258 }
259
260 #[inline]
262 pub fn reserve_exact(&mut self, additional: usize) {
263 self.vec.reserve_exact(additional)
264 }
265
266 #[inline]
268 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
269 self.vec.try_reserve(additional)
270 }
271
272 #[inline]
274 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
275 self.vec.try_reserve_exact(additional)
276 }
277
278 #[inline]
280 pub fn shrink_to_fit(&mut self) {
281 self.vec.shrink_to_fit()
282 }
283
284 #[inline]
286 pub fn shrink_to(&mut self, min_capacity: usize) {
287 self.vec.shrink_to(min_capacity)
288 }
289
290 #[inline]
292 pub fn push(&mut self, ch: char) {
293 match ch.len_utf8() {
294 1 => self.vec.push(ch as u8),
295 _ => self
296 .vec
297 .extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
298 }
299 }
300
301 #[inline]
303 pub fn push_java(&mut self, ch: JavaCodePoint) {
304 match ch.len_utf8() {
305 1 => self.vec.push(ch.as_u32() as u8),
306 _ => self.vec.extend_from_slice(ch.encode_semi_utf8(&mut [0; 4])),
307 }
308 }
309
310 #[inline]
312 #[must_use]
313 pub const fn as_bytes(&self) -> &[u8] {
314 self.vec.as_slice()
315 }
316
317 #[inline]
319 pub fn truncate(&mut self, new_len: usize) {
320 if new_len <= self.len() {
321 assert!(self.is_char_boundary(new_len));
322 self.vec.truncate(new_len)
323 }
324 }
325
326 #[inline]
342 pub fn pop(&mut self) -> Option<JavaCodePoint> {
343 let ch = self.chars().next_back()?;
344 let newlen = self.len() - ch.len_utf8();
345 unsafe { self.vec.set_len(newlen) };
346 Some(ch)
347 }
348
349 #[inline]
373 pub fn remove(&mut self, idx: usize) -> JavaCodePoint {
374 let Some(ch) = self[idx..].chars().next() else {
375 panic!("cannot remove a char from the end of a string")
376 };
377
378 let next = idx + ch.len_utf8();
379 let len = self.len();
380 unsafe {
381 ptr::copy(
382 self.vec.as_ptr().add(next),
383 self.vec.as_mut_ptr().add(idx),
384 len - next,
385 );
386 self.vec.set_len(len - (next - idx))
387 };
388 ch
389 }
390
391 #[inline]
403 pub fn retain<F>(&mut self, mut f: F)
404 where
405 F: FnMut(JavaCodePoint) -> bool,
406 {
407 struct SetLenOnDrop<'a> {
408 s: &'a mut JavaString,
409 idx: usize,
410 del_bytes: usize,
411 }
412
413 impl Drop for SetLenOnDrop<'_> {
414 #[inline]
415 fn drop(&mut self) {
416 let new_len = self.idx - self.del_bytes;
417 debug_assert!(new_len <= self.s.len());
418 unsafe { self.s.vec.set_len(new_len) };
419 }
420 }
421
422 let len = self.len();
423 let mut guard = SetLenOnDrop {
424 s: self,
425 idx: 0,
426 del_bytes: 0,
427 };
428
429 while guard.idx < len {
430 let ch = unsafe {
435 guard
436 .s
437 .get_unchecked(guard.idx..len)
438 .chars()
439 .next()
440 .unwrap_unchecked()
441 };
442 let ch_len = ch.len_utf8();
443
444 if !f(ch) {
445 guard.del_bytes += ch_len;
446 } else if guard.del_bytes > 0 {
447 ch.encode_semi_utf8(unsafe {
454 slice::from_raw_parts_mut(
455 guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes),
456 ch.len_utf8(),
457 )
458 });
459 }
460
461 guard.idx += ch_len;
463 }
464
465 drop(guard);
466 }
467
468 #[inline]
479 pub fn insert(&mut self, idx: usize, ch: char) {
480 assert!(self.is_char_boundary(idx));
481 let mut bits = [0; 4];
482 let bits = ch.encode_utf8(&mut bits).as_bytes();
483
484 unsafe {
485 self.insert_bytes(idx, bits);
486 }
487 }
488
489 #[inline]
491 pub fn insert_java(&mut self, idx: usize, ch: JavaCodePoint) {
492 assert!(self.is_char_boundary(idx));
493 let mut bits = [0; 4];
494 let bits = ch.encode_semi_utf8(&mut bits);
495
496 unsafe {
497 self.insert_bytes(idx, bits);
498 }
499 }
500
501 #[inline]
502 unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
503 let len = self.len();
504 let amt = bytes.len();
505 self.vec.reserve(amt);
506
507 unsafe {
508 ptr::copy(
509 self.vec.as_ptr().add(idx),
510 self.vec.as_mut_ptr().add(idx + amt),
511 len - idx,
512 );
513 ptr::copy_nonoverlapping(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
514 self.vec.set_len(len + amt);
515 }
516 }
517
518 #[inline]
527 pub fn insert_str(&mut self, idx: usize, string: &str) {
528 assert!(self.is_char_boundary(idx));
529
530 unsafe {
531 self.insert_bytes(idx, string.as_bytes());
532 }
533 }
534
535 pub fn insert_java_str(&mut self, idx: usize, string: &JavaStr) {
537 assert!(self.is_char_boundary(idx));
538
539 unsafe {
540 self.insert_bytes(idx, string.as_bytes());
541 }
542 }
543
544 #[inline]
551 pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
552 &mut self.vec
553 }
554
555 #[inline]
557 #[must_use]
558 pub const fn len(&self) -> usize {
559 self.vec.len()
560 }
561
562 #[inline]
564 #[must_use]
565 pub const fn is_empty(&self) -> bool {
566 self.len() == 0
567 }
568
569 #[inline]
585 #[must_use]
586 pub fn split_off(&mut self, at: usize) -> JavaString {
587 assert!(self.is_char_boundary(at));
588 let other = self.vec.split_off(at);
589 unsafe { JavaString::from_semi_utf8_unchecked(other) }
590 }
591
592 #[inline]
594 pub fn clear(&mut self) {
595 self.vec.clear();
596 }
597
598 #[inline]
616 pub fn drain<R>(&mut self, range: R) -> Drain<'_>
617 where
618 R: RangeBounds<usize>,
619 {
620 let Range { start, end } = to_range_checked(range, ..self.len());
622 assert!(self.is_char_boundary(start));
623 assert!(self.is_char_boundary(end));
624
625 let self_ptr = self as *mut _;
628 let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
631
632 Drain {
633 start,
634 end,
635 iter: chars_iter,
636 string: self_ptr,
637 }
638 }
639
640 pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
659 where
660 R: RangeBounds<usize>,
661 {
662 self.replace_range_java(range, JavaStr::from_str(replace_with))
663 }
664
665 pub fn replace_range_java<R>(&mut self, range: R, replace_with: &JavaStr)
667 where
668 R: RangeBounds<usize>,
669 {
670 let start = range.start_bound();
671 match start {
672 Bound::Included(&n) => assert!(self.is_char_boundary(n)),
673 Bound::Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
674 Bound::Unbounded => {}
675 };
676 let end = range.end_bound();
677 match end {
678 Bound::Included(&n) => assert!(self.is_char_boundary(n + 1)),
679 Bound::Excluded(&n) => assert!(self.is_char_boundary(n)),
680 Bound::Unbounded => {}
681 };
682
683 unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
684 }
685
686 #[inline]
688 #[must_use]
689 pub fn into_boxed_str(self) -> Box<JavaStr> {
690 let slice = self.vec.into_boxed_slice();
691 unsafe { JavaStr::from_boxed_semi_utf8_unchecked(slice) }
692 }
693
694 #[inline]
696 pub fn leak<'a>(self) -> &'a mut JavaStr {
697 let slice = self.vec.leak();
698 unsafe { JavaStr::from_semi_utf8_unchecked_mut(slice) }
699 }
700}
701
702impl Add<&str> for JavaString {
703 type Output = JavaString;
704
705 #[inline]
706 fn add(mut self, rhs: &str) -> Self::Output {
707 self.push_str(rhs);
708 self
709 }
710}
711
712impl Add<&JavaStr> for JavaString {
713 type Output = JavaString;
714
715 #[inline]
716 fn add(mut self, rhs: &JavaStr) -> Self::Output {
717 self.push_java_str(rhs);
718 self
719 }
720}
721
722impl AddAssign<&str> for JavaString {
723 #[inline]
724 fn add_assign(&mut self, rhs: &str) {
725 self.push_str(rhs);
726 }
727}
728
729impl AddAssign<&JavaStr> for JavaString {
730 #[inline]
731 fn add_assign(&mut self, rhs: &JavaStr) {
732 self.push_java_str(rhs);
733 }
734}
735
736impl AsMut<JavaStr> for JavaString {
737 #[inline]
738 fn as_mut(&mut self) -> &mut JavaStr {
739 self.as_mut_java_str()
740 }
741}
742
743impl AsRef<[u8]> for JavaString {
744 #[inline]
745 fn as_ref(&self) -> &[u8] {
746 self.as_bytes()
747 }
748}
749
750impl AsRef<JavaStr> for JavaString {
751 #[inline]
752 fn as_ref(&self) -> &JavaStr {
753 self.as_java_str()
754 }
755}
756
757impl Borrow<JavaStr> for JavaString {
758 #[inline]
759 fn borrow(&self) -> &JavaStr {
760 self.as_java_str()
761 }
762}
763
764impl BorrowMut<JavaStr> for JavaString {
765 #[inline]
766 fn borrow_mut(&mut self) -> &mut JavaStr {
767 self.as_mut_java_str()
768 }
769}
770
771impl Clone for JavaString {
772 #[inline]
773 fn clone(&self) -> Self {
774 JavaString {
775 vec: self.vec.clone(),
776 }
777 }
778
779 #[inline]
780 fn clone_from(&mut self, source: &Self) {
781 self.vec.clone_from(&source.vec)
782 }
783}
784
785impl Debug for JavaString {
786 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
787 Debug::fmt(&**self, f)
788 }
789}
790
791impl Deref for JavaString {
792 type Target = JavaStr;
793
794 #[inline]
795 fn deref(&self) -> &Self::Target {
796 self.as_java_str()
797 }
798}
799
800impl DerefMut for JavaString {
801 #[inline]
802 fn deref_mut(&mut self) -> &mut Self::Target {
803 self.as_mut_java_str()
804 }
805}
806
807impl Display for JavaString {
808 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
809 Display::fmt(&**self, f)
810 }
811}
812
813impl Extend<char> for JavaString {
814 fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
815 let iterator = iter.into_iter();
816 let (lower_bound, _) = iterator.size_hint();
817 self.reserve(lower_bound);
818 iterator.for_each(move |c| self.push(c));
819 }
820}
821
822impl Extend<JavaCodePoint> for JavaString {
823 fn extend<T: IntoIterator<Item = JavaCodePoint>>(&mut self, iter: T) {
824 let iterator = iter.into_iter();
825 let (lower_bound, _) = iterator.size_hint();
826 self.reserve(lower_bound);
827 iterator.for_each(move |c| self.push_java(c));
828 }
829}
830
831impl Extend<String> for JavaString {
832 fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
833 iter.into_iter().for_each(move |s| self.push_str(&s));
834 }
835}
836
837impl Extend<JavaString> for JavaString {
838 fn extend<T: IntoIterator<Item = JavaString>>(&mut self, iter: T) {
839 iter.into_iter().for_each(move |s| self.push_java_str(&s));
840 }
841}
842
843impl<'a> Extend<&'a char> for JavaString {
844 fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
845 self.extend(iter.into_iter().copied())
846 }
847}
848
849impl<'a> Extend<&'a JavaCodePoint> for JavaString {
850 fn extend<T: IntoIterator<Item = &'a JavaCodePoint>>(&mut self, iter: T) {
851 self.extend(iter.into_iter().copied())
852 }
853}
854
855impl<'a> Extend<&'a str> for JavaString {
856 fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
857 iter.into_iter().for_each(move |s| self.push_str(s));
858 }
859}
860
861impl<'a> Extend<&'a JavaStr> for JavaString {
862 fn extend<T: IntoIterator<Item = &'a JavaStr>>(&mut self, iter: T) {
863 iter.into_iter().for_each(move |s| self.push_java_str(s));
864 }
865}
866
867impl Extend<Box<str>> for JavaString {
868 fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
869 iter.into_iter().for_each(move |s| self.push_str(&s));
870 }
871}
872
873impl Extend<Box<JavaStr>> for JavaString {
874 fn extend<T: IntoIterator<Item = Box<JavaStr>>>(&mut self, iter: T) {
875 iter.into_iter().for_each(move |s| self.push_java_str(&s));
876 }
877}
878
879impl<'a> Extend<Cow<'a, str>> for JavaString {
880 fn extend<T: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: T) {
881 iter.into_iter().for_each(move |s| self.push_str(&s));
882 }
883}
884
885impl<'a> Extend<Cow<'a, JavaStr>> for JavaString {
886 fn extend<T: IntoIterator<Item = Cow<'a, JavaStr>>>(&mut self, iter: T) {
887 iter.into_iter().for_each(move |s| self.push_java_str(&s));
888 }
889}
890
891impl From<String> for JavaString {
892 #[inline]
893 fn from(value: String) -> Self {
894 unsafe {
895 JavaString::from_semi_utf8_unchecked(value.into_bytes())
897 }
898 }
899}
900
901impl From<&String> for JavaString {
902 #[inline]
903 fn from(value: &String) -> Self {
904 Self::from(value.clone())
905 }
906}
907
908impl From<&JavaString> for JavaString {
909 #[inline]
910 fn from(value: &JavaString) -> Self {
911 value.clone()
912 }
913}
914
915impl From<&mut str> for JavaString {
916 #[inline]
917 fn from(value: &mut str) -> Self {
918 Self::from(&*value)
919 }
920}
921
922impl From<&str> for JavaString {
923 #[inline]
924 fn from(value: &str) -> Self {
925 Self::from(value.to_owned())
926 }
927}
928
929impl From<&mut JavaStr> for JavaString {
930 #[inline]
931 fn from(value: &mut JavaStr) -> Self {
932 Self::from(&*value)
933 }
934}
935
936impl From<&JavaStr> for JavaString {
937 #[inline]
938 fn from(value: &JavaStr) -> Self {
939 value.to_owned()
940 }
941}
942
943impl From<Box<str>> for JavaString {
944 #[inline]
945 fn from(value: Box<str>) -> Self {
946 Self::from(value.into_string())
947 }
948}
949
950impl From<Box<JavaStr>> for JavaString {
951 #[inline]
952 fn from(value: Box<JavaStr>) -> Self {
953 value.into_string()
954 }
955}
956
957impl<'a> From<Cow<'a, str>> for JavaString {
958 #[inline]
959 fn from(value: Cow<'a, str>) -> Self {
960 Self::from(value.into_owned())
961 }
962}
963
964impl<'a> From<Cow<'a, JavaStr>> for JavaString {
965 #[inline]
966 fn from(value: Cow<'a, JavaStr>) -> Self {
967 value.into_owned()
968 }
969}
970
971impl From<JavaString> for Arc<JavaStr> {
972 #[inline]
973 fn from(value: JavaString) -> Self {
974 Arc::from(&value[..])
975 }
976}
977
978impl From<JavaString> for Cow<'_, JavaStr> {
979 #[inline]
980 fn from(value: JavaString) -> Self {
981 Cow::Owned(value)
982 }
983}
984
985impl From<JavaString> for Rc<JavaStr> {
986 #[inline]
987 fn from(value: JavaString) -> Self {
988 Rc::from(&value[..])
989 }
990}
991
992impl From<JavaString> for Vec<u8> {
993 #[inline]
994 fn from(value: JavaString) -> Self {
995 value.into_bytes()
996 }
997}
998
999impl From<char> for JavaString {
1000 #[inline]
1001 fn from(value: char) -> Self {
1002 Self::from(value.encode_utf8(&mut [0; 4]))
1003 }
1004}
1005
1006impl From<JavaCodePoint> for JavaString {
1007 #[inline]
1008 fn from(value: JavaCodePoint) -> Self {
1009 unsafe {
1010 JavaString::from_semi_utf8_unchecked(value.encode_semi_utf8(&mut [0; 4]).to_vec())
1012 }
1013 }
1014}
1015
1016impl TryFrom<Vec<u8>> for JavaString {
1017 type Error = FromUtf8Error;
1018
1019 #[inline]
1020 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
1021 JavaString::from_semi_utf8(value)
1022 }
1023}
1024
1025impl TryFrom<JavaString> for String {
1026 type Error = Utf8Error;
1027
1028 #[inline]
1029 fn try_from(value: JavaString) -> Result<Self, Self::Error> {
1030 value.into_string()
1031 }
1032}
1033
1034impl FromIterator<char> for JavaString {
1035 #[inline]
1036 fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
1037 let mut buf = JavaString::new();
1038 buf.extend(iter);
1039 buf
1040 }
1041}
1042
1043impl<'a> FromIterator<&'a char> for JavaString {
1044 #[inline]
1045 fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
1046 let mut buf = JavaString::new();
1047 buf.extend(iter);
1048 buf
1049 }
1050}
1051
1052impl FromIterator<JavaCodePoint> for JavaString {
1053 #[inline]
1054 fn from_iter<T: IntoIterator<Item = JavaCodePoint>>(iter: T) -> Self {
1055 let mut buf = JavaString::new();
1056 buf.extend(iter);
1057 buf
1058 }
1059}
1060
1061impl<'a> FromIterator<&'a JavaCodePoint> for JavaString {
1062 #[inline]
1063 fn from_iter<T: IntoIterator<Item = &'a JavaCodePoint>>(iter: T) -> Self {
1064 let mut buf = JavaString::new();
1065 buf.extend(iter);
1066 buf
1067 }
1068}
1069
1070impl<'a> FromIterator<&'a str> for JavaString {
1071 #[inline]
1072 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
1073 let mut buf = JavaString::new();
1074 buf.extend(iter);
1075 buf
1076 }
1077}
1078
1079impl<'a> FromIterator<&'a JavaStr> for JavaString {
1080 #[inline]
1081 fn from_iter<T: IntoIterator<Item = &'a JavaStr>>(iter: T) -> Self {
1082 let mut buf = JavaString::new();
1083 buf.extend(iter);
1084 buf
1085 }
1086}
1087
1088impl FromIterator<String> for JavaString {
1089 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
1090 let mut iterator = iter.into_iter();
1091
1092 match iterator.next() {
1093 None => JavaString::new(),
1094 Some(buf) => {
1095 let mut buf = JavaString::from(buf);
1096 buf.extend(iterator);
1097 buf
1098 }
1099 }
1100 }
1101}
1102
1103impl FromIterator<JavaString> for JavaString {
1104 fn from_iter<T: IntoIterator<Item = JavaString>>(iter: T) -> Self {
1105 let mut iterator = iter.into_iter();
1106
1107 match iterator.next() {
1108 None => JavaString::new(),
1109 Some(mut buf) => {
1110 buf.extend(iterator);
1111 buf
1112 }
1113 }
1114 }
1115}
1116
1117impl FromIterator<Box<str>> for JavaString {
1118 #[inline]
1119 fn from_iter<T: IntoIterator<Item = Box<str>>>(iter: T) -> Self {
1120 let mut buf = JavaString::new();
1121 buf.extend(iter);
1122 buf
1123 }
1124}
1125
1126impl FromIterator<Box<JavaStr>> for JavaString {
1127 #[inline]
1128 fn from_iter<T: IntoIterator<Item = Box<JavaStr>>>(iter: T) -> Self {
1129 let mut buf = JavaString::new();
1130 buf.extend(iter);
1131 buf
1132 }
1133}
1134
1135impl<'a> FromIterator<Cow<'a, str>> for JavaString {
1136 #[inline]
1137 fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
1138 let mut buf = JavaString::new();
1139 buf.extend(iter);
1140 buf
1141 }
1142}
1143
1144impl<'a> FromIterator<Cow<'a, JavaStr>> for JavaString {
1145 #[inline]
1146 fn from_iter<T: IntoIterator<Item = Cow<'a, JavaStr>>>(iter: T) -> Self {
1147 let mut buf = JavaString::new();
1148 buf.extend(iter);
1149 buf
1150 }
1151}
1152
1153impl FromStr for JavaString {
1154 type Err = Infallible;
1155
1156 #[inline]
1157 fn from_str(s: &str) -> Result<Self, Self::Err> {
1158 Ok(Self::from(s))
1159 }
1160}
1161
1162impl Hash for JavaString {
1163 #[inline]
1164 fn hash<H: Hasher>(&self, state: &mut H) {
1165 (**self).hash(state)
1166 }
1167}
1168
1169impl Index<Range<usize>> for JavaString {
1170 type Output = JavaStr;
1171
1172 #[inline]
1173 fn index(&self, index: Range<usize>) -> &Self::Output {
1174 &self[..][index]
1175 }
1176}
1177
1178impl Index<RangeFrom<usize>> for JavaString {
1179 type Output = JavaStr;
1180
1181 #[inline]
1182 fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
1183 &self[..][index]
1184 }
1185}
1186
1187impl Index<RangeFull> for JavaString {
1188 type Output = JavaStr;
1189
1190 #[inline]
1191 fn index(&self, _index: RangeFull) -> &Self::Output {
1192 self.as_java_str()
1193 }
1194}
1195
1196impl Index<RangeInclusive<usize>> for JavaString {
1197 type Output = JavaStr;
1198
1199 #[inline]
1200 fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
1201 &self[..][index]
1202 }
1203}
1204
1205impl Index<RangeTo<usize>> for JavaString {
1206 type Output = JavaStr;
1207
1208 #[inline]
1209 fn index(&self, index: RangeTo<usize>) -> &Self::Output {
1210 &self[..][index]
1211 }
1212}
1213
1214impl Index<RangeToInclusive<usize>> for JavaString {
1215 type Output = JavaStr;
1216
1217 #[inline]
1218 fn index(&self, index: RangeToInclusive<usize>) -> &Self::Output {
1219 &self[..][index]
1220 }
1221}
1222
1223impl IndexMut<Range<usize>> for JavaString {
1224 #[inline]
1225 fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
1226 &mut self[..][index]
1227 }
1228}
1229
1230impl IndexMut<RangeFrom<usize>> for JavaString {
1231 #[inline]
1232 fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
1233 &mut self[..][index]
1234 }
1235}
1236
1237impl IndexMut<RangeFull> for JavaString {
1238 #[inline]
1239 fn index_mut(&mut self, _index: RangeFull) -> &mut Self::Output {
1240 self.as_mut_java_str()
1241 }
1242}
1243
1244impl IndexMut<RangeInclusive<usize>> for JavaString {
1245 #[inline]
1246 fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
1247 &mut self[..][index]
1248 }
1249}
1250
1251impl IndexMut<RangeTo<usize>> for JavaString {
1252 #[inline]
1253 fn index_mut(&mut self, index: RangeTo<usize>) -> &mut Self::Output {
1254 &mut self[..][index]
1255 }
1256}
1257
1258impl IndexMut<RangeToInclusive<usize>> for JavaString {
1259 #[inline]
1260 fn index_mut(&mut self, index: RangeToInclusive<usize>) -> &mut Self::Output {
1261 &mut self[..][index]
1262 }
1263}
1264
1265impl PartialEq<str> for JavaString {
1266 #[inline]
1267 fn eq(&self, other: &str) -> bool {
1268 self[..] == other
1269 }
1270}
1271
1272impl PartialEq<JavaString> for str {
1273 #[inline]
1274 fn eq(&self, other: &JavaString) -> bool {
1275 self == other[..]
1276 }
1277}
1278
1279impl<'a> PartialEq<&'a str> for JavaString {
1280 #[inline]
1281 fn eq(&self, other: &&'a str) -> bool {
1282 self == *other
1283 }
1284}
1285
1286impl PartialEq<JavaString> for &str {
1287 #[inline]
1288 fn eq(&self, other: &JavaString) -> bool {
1289 *self == other
1290 }
1291}
1292
1293impl PartialEq<String> for JavaString {
1294 #[inline]
1295 fn eq(&self, other: &String) -> bool {
1296 &self[..] == other
1297 }
1298}
1299
1300impl PartialEq<JavaString> for String {
1301 #[inline]
1302 fn eq(&self, other: &JavaString) -> bool {
1303 self == &other[..]
1304 }
1305}
1306
1307impl PartialEq<JavaStr> for JavaString {
1308 #[inline]
1309 fn eq(&self, other: &JavaStr) -> bool {
1310 self[..] == other
1311 }
1312}
1313
1314impl<'a> PartialEq<&'a JavaStr> for JavaString {
1315 #[inline]
1316 fn eq(&self, other: &&'a JavaStr) -> bool {
1317 self == *other
1318 }
1319}
1320
1321impl<'a> PartialEq<Cow<'a, str>> for JavaString {
1322 #[inline]
1323 fn eq(&self, other: &Cow<'a, str>) -> bool {
1324 &self[..] == other
1325 }
1326}
1327
1328impl PartialEq<JavaString> for Cow<'_, str> {
1329 #[inline]
1330 fn eq(&self, other: &JavaString) -> bool {
1331 self == &other[..]
1332 }
1333}
1334
1335impl<'a> PartialEq<Cow<'a, JavaStr>> for JavaString {
1336 #[inline]
1337 fn eq(&self, other: &Cow<'a, JavaStr>) -> bool {
1338 &self[..] == other
1339 }
1340}
1341
1342impl PartialEq<JavaString> for Cow<'_, JavaStr> {
1343 #[inline]
1344 fn eq(&self, other: &JavaString) -> bool {
1345 self == &other[..]
1346 }
1347}
1348
1349impl Write for JavaString {
1350 #[inline]
1351 fn write_str(&mut self, s: &str) -> std::fmt::Result {
1352 self.push_str(s);
1353 Ok(())
1354 }
1355
1356 #[inline]
1357 fn write_char(&mut self, c: char) -> std::fmt::Result {
1358 self.push(c);
1359 Ok(())
1360 }
1361}
1362
1363pub struct Drain<'a> {
1364 string: *mut JavaString,
1365 start: usize,
1366 end: usize,
1367 iter: Chars<'a>,
1368}
1369
1370impl Debug for Drain<'_> {
1371 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1372 f.debug_tuple("Drain").field(&self.as_str()).finish()
1373 }
1374}
1375
1376unsafe impl Sync for Drain<'_> {}
1377unsafe impl Send for Drain<'_> {}
1378
1379impl Drop for Drain<'_> {
1380 #[inline]
1381 fn drop(&mut self) {
1382 unsafe {
1383 let self_vec = (*self.string).as_mut_vec();
1386 if self.start <= self.end && self.end <= self_vec.len() {
1387 self_vec.drain(self.start..self.end);
1388 }
1389 }
1390 }
1391}
1392
1393impl AsRef<JavaStr> for Drain<'_> {
1394 #[inline]
1395 fn as_ref(&self) -> &JavaStr {
1396 self.as_str()
1397 }
1398}
1399
1400impl AsRef<[u8]> for Drain<'_> {
1401 #[inline]
1402 fn as_ref(&self) -> &[u8] {
1403 self.as_str().as_bytes()
1404 }
1405}
1406
1407impl Drain<'_> {
1408 #[inline]
1409 #[must_use]
1410 pub fn as_str(&self) -> &JavaStr {
1411 self.iter.as_str()
1412 }
1413}
1414
1415impl Iterator for Drain<'_> {
1416 type Item = JavaCodePoint;
1417
1418 #[inline]
1419 fn next(&mut self) -> Option<JavaCodePoint> {
1420 self.iter.next()
1421 }
1422
1423 #[inline]
1424 fn size_hint(&self) -> (usize, Option<usize>) {
1425 self.iter.size_hint()
1426 }
1427
1428 #[inline]
1429 fn last(mut self) -> Option<JavaCodePoint> {
1430 self.next_back()
1431 }
1432}
1433
1434impl DoubleEndedIterator for Drain<'_> {
1435 #[inline]
1436 fn next_back(&mut self) -> Option<Self::Item> {
1437 self.iter.next_back()
1438 }
1439}
1440
1441impl FusedIterator for Drain<'_> {}