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