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 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 { self.vec.set_len(newlen) };
330 Some(ch)
331 }
332
333 #[inline]
357 pub fn remove(&mut self, idx: usize) -> JavaCodePoint {
358 let Some(ch) = self[idx..].chars().next() else {
359 panic!("cannot remove a char from the end of a string")
360 };
361
362 let next = idx + ch.len_utf8();
363 let len = self.len();
364 unsafe {
365 ptr::copy(
366 self.vec.as_ptr().add(next),
367 self.vec.as_mut_ptr().add(idx),
368 len - next,
369 );
370 self.vec.set_len(len - (next - idx))
371 };
372 ch
373 }
374
375 #[inline]
387 pub fn retain<F>(&mut self, mut f: F)
388 where
389 F: FnMut(JavaCodePoint) -> bool,
390 {
391 struct SetLenOnDrop<'a> {
392 s: &'a mut JavaString,
393 idx: usize,
394 del_bytes: usize,
395 }
396
397 impl Drop for SetLenOnDrop<'_> {
398 #[inline]
399 fn drop(&mut self) {
400 let new_len = self.idx - self.del_bytes;
401 debug_assert!(new_len <= self.s.len());
402 unsafe { self.s.vec.set_len(new_len) };
403 }
404 }
405
406 let len = self.len();
407 let mut guard = SetLenOnDrop {
408 s: self,
409 idx: 0,
410 del_bytes: 0,
411 };
412
413 while guard.idx < len {
414 let ch = unsafe {
419 guard
420 .s
421 .get_unchecked(guard.idx..len)
422 .chars()
423 .next()
424 .unwrap_unchecked()
425 };
426 let ch_len = ch.len_utf8();
427
428 if !f(ch) {
429 guard.del_bytes += ch_len;
430 } else if guard.del_bytes > 0 {
431 ch.encode_semi_utf8(unsafe {
438 slice::from_raw_parts_mut(
439 guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes),
440 ch.len_utf8(),
441 )
442 });
443 }
444
445 guard.idx += ch_len;
447 }
448
449 drop(guard);
450 }
451
452 #[inline]
463 pub fn insert(&mut self, idx: usize, ch: char) {
464 assert!(self.is_char_boundary(idx));
465 let mut bits = [0; 4];
466 let bits = ch.encode_utf8(&mut bits).as_bytes();
467
468 unsafe {
469 self.insert_bytes(idx, bits);
470 }
471 }
472
473 #[inline]
475 pub fn insert_java(&mut self, idx: usize, ch: JavaCodePoint) {
476 assert!(self.is_char_boundary(idx));
477 let mut bits = [0; 4];
478 let bits = ch.encode_semi_utf8(&mut bits);
479
480 unsafe {
481 self.insert_bytes(idx, bits);
482 }
483 }
484
485 #[inline]
486 unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
487 let len = self.len();
488 let amt = bytes.len();
489 self.vec.reserve(amt);
490
491 unsafe {
492 ptr::copy(
493 self.vec.as_ptr().add(idx),
494 self.vec.as_mut_ptr().add(idx + amt),
495 len - idx,
496 );
497 ptr::copy_nonoverlapping(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
498 self.vec.set_len(len + amt);
499 }
500 }
501
502 #[inline]
511 pub fn insert_str(&mut self, idx: usize, string: &str) {
512 assert!(self.is_char_boundary(idx));
513
514 unsafe {
515 self.insert_bytes(idx, string.as_bytes());
516 }
517 }
518
519 pub fn insert_java_str(&mut self, idx: usize, string: &JavaStr) {
521 assert!(self.is_char_boundary(idx));
522
523 unsafe {
524 self.insert_bytes(idx, string.as_bytes());
525 }
526 }
527
528 #[inline]
535 pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
536 &mut self.vec
537 }
538
539 #[inline]
541 #[must_use]
542 pub fn len(&self) -> usize {
543 self.vec.len()
544 }
545
546 #[inline]
548 #[must_use]
549 pub fn is_empty(&self) -> bool {
550 self.len() == 0
551 }
552
553 #[inline]
569 #[must_use]
570 pub fn split_off(&mut self, at: usize) -> JavaString {
571 assert!(self.is_char_boundary(at));
572 let other = self.vec.split_off(at);
573 unsafe { JavaString::from_semi_utf8_unchecked(other) }
574 }
575
576 #[inline]
578 pub fn clear(&mut self) {
579 self.vec.clear();
580 }
581
582 #[inline]
600 pub fn drain<R>(&mut self, range: R) -> Drain<'_>
601 where
602 R: RangeBounds<usize>,
603 {
604 let Range { start, end } = to_range_checked(range, ..self.len());
606 assert!(self.is_char_boundary(start));
607 assert!(self.is_char_boundary(end));
608
609 let self_ptr = self as *mut _;
612 let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
615
616 Drain {
617 start,
618 end,
619 iter: chars_iter,
620 string: self_ptr,
621 }
622 }
623
624 pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
643 where
644 R: RangeBounds<usize>,
645 {
646 self.replace_range_java(range, JavaStr::from_str(replace_with))
647 }
648
649 pub fn replace_range_java<R>(&mut self, range: R, replace_with: &JavaStr)
651 where
652 R: RangeBounds<usize>,
653 {
654 let start = range.start_bound();
655 match start {
656 Bound::Included(&n) => assert!(self.is_char_boundary(n)),
657 Bound::Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
658 Bound::Unbounded => {}
659 };
660 let end = range.end_bound();
661 match end {
662 Bound::Included(&n) => assert!(self.is_char_boundary(n + 1)),
663 Bound::Excluded(&n) => assert!(self.is_char_boundary(n)),
664 Bound::Unbounded => {}
665 };
666
667 unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
668 }
669
670 #[inline]
672 #[must_use]
673 pub fn into_boxed_str(self) -> Box<JavaStr> {
674 let slice = self.vec.into_boxed_slice();
675 unsafe { JavaStr::from_boxed_semi_utf8_unchecked(slice) }
676 }
677
678 #[inline]
680 pub fn leak<'a>(self) -> &'a mut JavaStr {
681 let slice = self.vec.leak();
682 unsafe { JavaStr::from_semi_utf8_unchecked_mut(slice) }
683 }
684}
685
686impl Add<&str> for JavaString {
687 type Output = JavaString;
688
689 #[inline]
690 fn add(mut self, rhs: &str) -> Self::Output {
691 self.push_str(rhs);
692 self
693 }
694}
695
696impl Add<&JavaStr> for JavaString {
697 type Output = JavaString;
698
699 #[inline]
700 fn add(mut self, rhs: &JavaStr) -> Self::Output {
701 self.push_java_str(rhs);
702 self
703 }
704}
705
706impl AddAssign<&str> for JavaString {
707 #[inline]
708 fn add_assign(&mut self, rhs: &str) {
709 self.push_str(rhs);
710 }
711}
712
713impl AddAssign<&JavaStr> for JavaString {
714 #[inline]
715 fn add_assign(&mut self, rhs: &JavaStr) {
716 self.push_java_str(rhs);
717 }
718}
719
720impl AsMut<JavaStr> for JavaString {
721 #[inline]
722 fn as_mut(&mut self) -> &mut JavaStr {
723 self.as_mut_java_str()
724 }
725}
726
727impl AsRef<[u8]> for JavaString {
728 #[inline]
729 fn as_ref(&self) -> &[u8] {
730 self.as_bytes()
731 }
732}
733
734impl AsRef<JavaStr> for JavaString {
735 #[inline]
736 fn as_ref(&self) -> &JavaStr {
737 self.as_java_str()
738 }
739}
740
741impl Borrow<JavaStr> for JavaString {
742 #[inline]
743 fn borrow(&self) -> &JavaStr {
744 self.as_java_str()
745 }
746}
747
748impl BorrowMut<JavaStr> for JavaString {
749 #[inline]
750 fn borrow_mut(&mut self) -> &mut JavaStr {
751 self.as_mut_java_str()
752 }
753}
754
755impl Clone for JavaString {
756 #[inline]
757 fn clone(&self) -> Self {
758 JavaString {
759 vec: self.vec.clone(),
760 }
761 }
762
763 #[inline]
764 fn clone_from(&mut self, source: &Self) {
765 self.vec.clone_from(&source.vec)
766 }
767}
768
769impl Debug for JavaString {
770 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
771 Debug::fmt(&**self, f)
772 }
773}
774
775impl Deref for JavaString {
776 type Target = JavaStr;
777
778 #[inline]
779 fn deref(&self) -> &Self::Target {
780 self.as_java_str()
781 }
782}
783
784impl DerefMut for JavaString {
785 #[inline]
786 fn deref_mut(&mut self) -> &mut Self::Target {
787 self.as_mut_java_str()
788 }
789}
790
791impl Display for JavaString {
792 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
793 Display::fmt(&**self, f)
794 }
795}
796
797impl Extend<char> for JavaString {
798 fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
799 let iterator = iter.into_iter();
800 let (lower_bound, _) = iterator.size_hint();
801 self.reserve(lower_bound);
802 iterator.for_each(move |c| self.push(c));
803 }
804}
805
806impl Extend<JavaCodePoint> for JavaString {
807 fn extend<T: IntoIterator<Item = JavaCodePoint>>(&mut self, iter: T) {
808 let iterator = iter.into_iter();
809 let (lower_bound, _) = iterator.size_hint();
810 self.reserve(lower_bound);
811 iterator.for_each(move |c| self.push_java(c));
812 }
813}
814
815impl Extend<String> for JavaString {
816 fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
817 iter.into_iter().for_each(move |s| self.push_str(&s));
818 }
819}
820
821impl Extend<JavaString> for JavaString {
822 fn extend<T: IntoIterator<Item = JavaString>>(&mut self, iter: T) {
823 iter.into_iter().for_each(move |s| self.push_java_str(&s));
824 }
825}
826
827impl<'a> Extend<&'a char> for JavaString {
828 fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
829 self.extend(iter.into_iter().copied())
830 }
831}
832
833impl<'a> Extend<&'a JavaCodePoint> for JavaString {
834 fn extend<T: IntoIterator<Item = &'a JavaCodePoint>>(&mut self, iter: T) {
835 self.extend(iter.into_iter().copied())
836 }
837}
838
839impl<'a> Extend<&'a str> for JavaString {
840 fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
841 iter.into_iter().for_each(move |s| self.push_str(s));
842 }
843}
844
845impl<'a> Extend<&'a JavaStr> for JavaString {
846 fn extend<T: IntoIterator<Item = &'a JavaStr>>(&mut self, iter: T) {
847 iter.into_iter().for_each(move |s| self.push_java_str(s));
848 }
849}
850
851impl Extend<Box<str>> for JavaString {
852 fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
853 iter.into_iter().for_each(move |s| self.push_str(&s));
854 }
855}
856
857impl Extend<Box<JavaStr>> for JavaString {
858 fn extend<T: IntoIterator<Item = Box<JavaStr>>>(&mut self, iter: T) {
859 iter.into_iter().for_each(move |s| self.push_java_str(&s));
860 }
861}
862
863impl<'a> Extend<Cow<'a, str>> for JavaString {
864 fn extend<T: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: T) {
865 iter.into_iter().for_each(move |s| self.push_str(&s));
866 }
867}
868
869impl<'a> Extend<Cow<'a, JavaStr>> for JavaString {
870 fn extend<T: IntoIterator<Item = Cow<'a, JavaStr>>>(&mut self, iter: T) {
871 iter.into_iter().for_each(move |s| self.push_java_str(&s));
872 }
873}
874
875impl From<String> for JavaString {
876 #[inline]
877 fn from(value: String) -> Self {
878 unsafe {
879 JavaString::from_semi_utf8_unchecked(value.into_bytes())
881 }
882 }
883}
884
885impl From<&String> for JavaString {
886 #[inline]
887 fn from(value: &String) -> Self {
888 Self::from(value.clone())
889 }
890}
891
892impl From<&JavaString> for JavaString {
893 #[inline]
894 fn from(value: &JavaString) -> Self {
895 value.clone()
896 }
897}
898
899impl From<&mut str> for JavaString {
900 #[inline]
901 fn from(value: &mut str) -> Self {
902 Self::from(&*value)
903 }
904}
905
906impl From<&str> for JavaString {
907 #[inline]
908 fn from(value: &str) -> Self {
909 Self::from(value.to_owned())
910 }
911}
912
913impl From<&mut JavaStr> for JavaString {
914 #[inline]
915 fn from(value: &mut JavaStr) -> Self {
916 Self::from(&*value)
917 }
918}
919
920impl From<&JavaStr> for JavaString {
921 #[inline]
922 fn from(value: &JavaStr) -> Self {
923 value.to_owned()
924 }
925}
926
927impl From<Box<str>> for JavaString {
928 #[inline]
929 fn from(value: Box<str>) -> Self {
930 Self::from(value.into_string())
931 }
932}
933
934impl From<Box<JavaStr>> for JavaString {
935 #[inline]
936 fn from(value: Box<JavaStr>) -> Self {
937 value.into_string()
938 }
939}
940
941impl<'a> From<Cow<'a, str>> for JavaString {
942 #[inline]
943 fn from(value: Cow<'a, str>) -> Self {
944 Self::from(value.into_owned())
945 }
946}
947
948impl<'a> From<Cow<'a, JavaStr>> for JavaString {
949 #[inline]
950 fn from(value: Cow<'a, JavaStr>) -> Self {
951 value.into_owned()
952 }
953}
954
955impl From<JavaString> for Arc<JavaStr> {
956 #[inline]
957 fn from(value: JavaString) -> Self {
958 Arc::from(&value[..])
959 }
960}
961
962impl From<JavaString> for Cow<'_, JavaStr> {
963 #[inline]
964 fn from(value: JavaString) -> Self {
965 Cow::Owned(value)
966 }
967}
968
969impl From<JavaString> for Rc<JavaStr> {
970 #[inline]
971 fn from(value: JavaString) -> Self {
972 Rc::from(&value[..])
973 }
974}
975
976impl From<JavaString> for Vec<u8> {
977 #[inline]
978 fn from(value: JavaString) -> Self {
979 value.into_bytes()
980 }
981}
982
983impl From<char> for JavaString {
984 #[inline]
985 fn from(value: char) -> Self {
986 Self::from(value.encode_utf8(&mut [0; 4]))
987 }
988}
989
990impl From<JavaCodePoint> for JavaString {
991 #[inline]
992 fn from(value: JavaCodePoint) -> Self {
993 unsafe {
994 JavaString::from_semi_utf8_unchecked(value.encode_semi_utf8(&mut [0; 4]).to_vec())
996 }
997 }
998}
999
1000impl FromIterator<char> for JavaString {
1001 #[inline]
1002 fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
1003 let mut buf = JavaString::new();
1004 buf.extend(iter);
1005 buf
1006 }
1007}
1008
1009impl<'a> FromIterator<&'a char> for JavaString {
1010 #[inline]
1011 fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
1012 let mut buf = JavaString::new();
1013 buf.extend(iter);
1014 buf
1015 }
1016}
1017
1018impl FromIterator<JavaCodePoint> for JavaString {
1019 #[inline]
1020 fn from_iter<T: IntoIterator<Item = JavaCodePoint>>(iter: T) -> Self {
1021 let mut buf = JavaString::new();
1022 buf.extend(iter);
1023 buf
1024 }
1025}
1026
1027impl<'a> FromIterator<&'a JavaCodePoint> for JavaString {
1028 #[inline]
1029 fn from_iter<T: IntoIterator<Item = &'a JavaCodePoint>>(iter: T) -> Self {
1030 let mut buf = JavaString::new();
1031 buf.extend(iter);
1032 buf
1033 }
1034}
1035
1036impl<'a> FromIterator<&'a str> for JavaString {
1037 #[inline]
1038 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
1039 let mut buf = JavaString::new();
1040 buf.extend(iter);
1041 buf
1042 }
1043}
1044
1045impl FromIterator<String> for JavaString {
1046 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
1047 let mut iterator = iter.into_iter();
1048
1049 match iterator.next() {
1050 None => JavaString::new(),
1051 Some(buf) => {
1052 let mut buf = JavaString::from(buf);
1053 buf.extend(iterator);
1054 buf
1055 }
1056 }
1057 }
1058}
1059
1060impl FromIterator<JavaString> for JavaString {
1061 fn from_iter<T: IntoIterator<Item = JavaString>>(iter: T) -> Self {
1062 let mut iterator = iter.into_iter();
1063
1064 match iterator.next() {
1065 None => JavaString::new(),
1066 Some(mut buf) => {
1067 buf.extend(iterator);
1068 buf
1069 }
1070 }
1071 }
1072}
1073
1074impl FromIterator<Box<str>> for JavaString {
1075 #[inline]
1076 fn from_iter<T: IntoIterator<Item = Box<str>>>(iter: T) -> Self {
1077 let mut buf = JavaString::new();
1078 buf.extend(iter);
1079 buf
1080 }
1081}
1082
1083impl FromIterator<Box<JavaStr>> for JavaString {
1084 #[inline]
1085 fn from_iter<T: IntoIterator<Item = Box<JavaStr>>>(iter: T) -> Self {
1086 let mut buf = JavaString::new();
1087 buf.extend(iter);
1088 buf
1089 }
1090}
1091
1092impl<'a> FromIterator<Cow<'a, str>> for JavaString {
1093 #[inline]
1094 fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
1095 let mut buf = JavaString::new();
1096 buf.extend(iter);
1097 buf
1098 }
1099}
1100
1101impl<'a> FromIterator<Cow<'a, JavaStr>> for JavaString {
1102 #[inline]
1103 fn from_iter<T: IntoIterator<Item = Cow<'a, JavaStr>>>(iter: T) -> Self {
1104 let mut buf = JavaString::new();
1105 buf.extend(iter);
1106 buf
1107 }
1108}
1109
1110impl FromStr for JavaString {
1111 type Err = Infallible;
1112
1113 #[inline]
1114 fn from_str(s: &str) -> Result<Self, Self::Err> {
1115 Ok(Self::from(s))
1116 }
1117}
1118
1119impl Hash for JavaString {
1120 #[inline]
1121 fn hash<H: Hasher>(&self, state: &mut H) {
1122 (**self).hash(state)
1123 }
1124}
1125
1126impl Index<Range<usize>> for JavaString {
1127 type Output = JavaStr;
1128
1129 #[inline]
1130 fn index(&self, index: Range<usize>) -> &Self::Output {
1131 &self[..][index]
1132 }
1133}
1134
1135impl Index<RangeFrom<usize>> for JavaString {
1136 type Output = JavaStr;
1137
1138 #[inline]
1139 fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
1140 &self[..][index]
1141 }
1142}
1143
1144impl Index<RangeFull> for JavaString {
1145 type Output = JavaStr;
1146
1147 #[inline]
1148 fn index(&self, _index: RangeFull) -> &Self::Output {
1149 self.as_java_str()
1150 }
1151}
1152
1153impl Index<RangeInclusive<usize>> for JavaString {
1154 type Output = JavaStr;
1155
1156 #[inline]
1157 fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
1158 &self[..][index]
1159 }
1160}
1161
1162impl Index<RangeTo<usize>> for JavaString {
1163 type Output = JavaStr;
1164
1165 #[inline]
1166 fn index(&self, index: RangeTo<usize>) -> &Self::Output {
1167 &self[..][index]
1168 }
1169}
1170
1171impl Index<RangeToInclusive<usize>> for JavaString {
1172 type Output = JavaStr;
1173
1174 #[inline]
1175 fn index(&self, index: RangeToInclusive<usize>) -> &Self::Output {
1176 &self[..][index]
1177 }
1178}
1179
1180impl IndexMut<Range<usize>> for JavaString {
1181 #[inline]
1182 fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
1183 &mut self[..][index]
1184 }
1185}
1186
1187impl IndexMut<RangeFrom<usize>> for JavaString {
1188 #[inline]
1189 fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
1190 &mut self[..][index]
1191 }
1192}
1193
1194impl IndexMut<RangeFull> for JavaString {
1195 #[inline]
1196 fn index_mut(&mut self, _index: RangeFull) -> &mut Self::Output {
1197 self.as_mut_java_str()
1198 }
1199}
1200
1201impl IndexMut<RangeInclusive<usize>> for JavaString {
1202 #[inline]
1203 fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
1204 &mut self[..][index]
1205 }
1206}
1207
1208impl IndexMut<RangeTo<usize>> for JavaString {
1209 #[inline]
1210 fn index_mut(&mut self, index: RangeTo<usize>) -> &mut Self::Output {
1211 &mut self[..][index]
1212 }
1213}
1214
1215impl IndexMut<RangeToInclusive<usize>> for JavaString {
1216 #[inline]
1217 fn index_mut(&mut self, index: RangeToInclusive<usize>) -> &mut Self::Output {
1218 &mut self[..][index]
1219 }
1220}
1221
1222impl PartialEq<str> for JavaString {
1223 #[inline]
1224 fn eq(&self, other: &str) -> bool {
1225 self[..] == other
1226 }
1227}
1228
1229impl PartialEq<JavaString> for str {
1230 #[inline]
1231 fn eq(&self, other: &JavaString) -> bool {
1232 self == other[..]
1233 }
1234}
1235
1236impl<'a> PartialEq<&'a str> for JavaString {
1237 #[inline]
1238 fn eq(&self, other: &&'a str) -> bool {
1239 self == *other
1240 }
1241}
1242
1243impl PartialEq<JavaString> for &str {
1244 #[inline]
1245 fn eq(&self, other: &JavaString) -> bool {
1246 *self == other
1247 }
1248}
1249
1250impl PartialEq<String> for JavaString {
1251 #[inline]
1252 fn eq(&self, other: &String) -> bool {
1253 &self[..] == other
1254 }
1255}
1256
1257impl PartialEq<JavaString> for String {
1258 #[inline]
1259 fn eq(&self, other: &JavaString) -> bool {
1260 self == &other[..]
1261 }
1262}
1263
1264impl PartialEq<JavaStr> for JavaString {
1265 #[inline]
1266 fn eq(&self, other: &JavaStr) -> bool {
1267 self[..] == other
1268 }
1269}
1270
1271impl<'a> PartialEq<&'a JavaStr> for JavaString {
1272 #[inline]
1273 fn eq(&self, other: &&'a JavaStr) -> bool {
1274 self == *other
1275 }
1276}
1277
1278impl<'a> PartialEq<Cow<'a, str>> for JavaString {
1279 #[inline]
1280 fn eq(&self, other: &Cow<'a, str>) -> bool {
1281 &self[..] == other
1282 }
1283}
1284
1285impl PartialEq<JavaString> for Cow<'_, str> {
1286 #[inline]
1287 fn eq(&self, other: &JavaString) -> bool {
1288 self == &other[..]
1289 }
1290}
1291
1292impl<'a> PartialEq<Cow<'a, JavaStr>> for JavaString {
1293 #[inline]
1294 fn eq(&self, other: &Cow<'a, JavaStr>) -> bool {
1295 &self[..] == other
1296 }
1297}
1298
1299impl PartialEq<JavaString> for Cow<'_, JavaStr> {
1300 #[inline]
1301 fn eq(&self, other: &JavaString) -> bool {
1302 self == &other[..]
1303 }
1304}
1305
1306impl Write for JavaString {
1307 #[inline]
1308 fn write_str(&mut self, s: &str) -> std::fmt::Result {
1309 self.push_str(s);
1310 Ok(())
1311 }
1312
1313 #[inline]
1314 fn write_char(&mut self, c: char) -> std::fmt::Result {
1315 self.push(c);
1316 Ok(())
1317 }
1318}
1319
1320pub struct Drain<'a> {
1321 string: *mut JavaString,
1322 start: usize,
1323 end: usize,
1324 iter: Chars<'a>,
1325}
1326
1327impl Debug for Drain<'_> {
1328 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1329 f.debug_tuple("Drain").field(&self.as_str()).finish()
1330 }
1331}
1332
1333unsafe impl Sync for Drain<'_> {}
1334unsafe impl Send for Drain<'_> {}
1335
1336impl Drop for Drain<'_> {
1337 #[inline]
1338 fn drop(&mut self) {
1339 unsafe {
1340 let self_vec = (*self.string).as_mut_vec();
1343 if self.start <= self.end && self.end <= self_vec.len() {
1344 self_vec.drain(self.start..self.end);
1345 }
1346 }
1347 }
1348}
1349
1350impl AsRef<JavaStr> for Drain<'_> {
1351 #[inline]
1352 fn as_ref(&self) -> &JavaStr {
1353 self.as_str()
1354 }
1355}
1356
1357impl AsRef<[u8]> for Drain<'_> {
1358 #[inline]
1359 fn as_ref(&self) -> &[u8] {
1360 self.as_str().as_bytes()
1361 }
1362}
1363
1364impl Drain<'_> {
1365 #[inline]
1366 #[must_use]
1367 pub fn as_str(&self) -> &JavaStr {
1368 self.iter.as_str()
1369 }
1370}
1371
1372impl Iterator for Drain<'_> {
1373 type Item = JavaCodePoint;
1374
1375 #[inline]
1376 fn next(&mut self) -> Option<JavaCodePoint> {
1377 self.iter.next()
1378 }
1379
1380 #[inline]
1381 fn size_hint(&self) -> (usize, Option<usize>) {
1382 self.iter.size_hint()
1383 }
1384
1385 #[inline]
1386 fn last(mut self) -> Option<JavaCodePoint> {
1387 self.next_back()
1388 }
1389}
1390
1391impl DoubleEndedIterator for Drain<'_> {
1392 #[inline]
1393 fn next_back(&mut self) -> Option<Self::Item> {
1394 self.iter.next_back()
1395 }
1396}
1397
1398impl FusedIterator for Drain<'_> {}