java_string/
owned.rs

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    /// Converts `vec` to a `JavaString` if it is fully-valid UTF-8, i.e. UTF-8
42    /// without surrogate code points. See [`String::from_utf8`].
43    #[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    /// Converts `vec` to a `JavaString` if it is semi-valid UTF-8, i.e. UTF-8
55    /// with surrogate code points.
56    ///
57    /// ```
58    /// # use java_string::{JavaCodePoint, JavaString};
59    ///
60    /// assert_eq!(
61    ///     JavaString::from_semi_utf8(b"Hello World!".to_vec()).unwrap(),
62    ///     "Hello World!"
63    /// );
64    /// assert_eq!(
65    ///     JavaString::from_semi_utf8(vec![0xf0, 0x9f, 0x92, 0x96]).unwrap(),
66    ///     "💖"
67    /// );
68    /// assert_eq!(
69    ///     JavaString::from_semi_utf8(vec![0xed, 0xa0, 0x80]).unwrap(),
70    ///     JavaString::from(JavaCodePoint::from_u32(0xd800).unwrap())
71    /// );
72    /// assert!(JavaString::from_semi_utf8(vec![0xed]).is_err());
73    /// ```
74    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    /// Converts `v` to a `Cow<JavaStr>`, replacing invalid semi-UTF-8 with the
85    /// replacement character �.
86    ///
87    /// ```
88    /// # use std::borrow::Cow;
89    /// # use java_string::{JavaStr, JavaString};
90    ///
91    /// let sparkle_heart = [0xf0, 0x9f, 0x92, 0x96];
92    /// let result = JavaString::from_semi_utf8_lossy(&sparkle_heart);
93    /// assert!(matches!(result, Cow::Borrowed(_)));
94    /// assert_eq!(result, JavaStr::from_str("💖"));
95    ///
96    /// let foobar_with_error = [b'f', b'o', b'o', 0xed, b'b', b'a', b'r'];
97    /// let result = JavaString::from_semi_utf8_lossy(&foobar_with_error);
98    /// assert!(matches!(result, Cow::Owned(_)));
99    /// assert_eq!(result, JavaStr::from_str("foo�bar"));
100    /// ```
101    #[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                // SAFETY: validation succeeded
108                Cow::Borrowed(JavaStr::from_semi_utf8_unchecked(v))
109            },
110            Err(error) => {
111                let mut result = unsafe {
112                    // SAFETY: validation succeeded up to this index
113                    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                                // SAFETY: validation succeeded
124                                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                                // SAFETY: validation succeeded up to this index
132                                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    /// # Safety
146    ///
147    /// The parameter must be in semi-valid UTF-8 format, that is, UTF-8 plus
148    /// surrogate code points.
149    #[inline]
150    #[must_use]
151    pub unsafe fn from_semi_utf8_unchecked(bytes: Vec<u8>) -> JavaString {
152        JavaString { vec: bytes }
153    }
154
155    /// See [`String::into_bytes`].
156    #[inline]
157    #[must_use]
158    pub fn into_bytes(self) -> Vec<u8> {
159        self.vec
160    }
161
162    /// See [`String::as_str`].
163    #[inline]
164    #[must_use]
165    pub fn as_java_str(&self) -> &JavaStr {
166        unsafe {
167            // SAFETY: this str has semi-valid UTF-8
168            JavaStr::from_semi_utf8_unchecked(&self.vec)
169        }
170    }
171
172    /// See [`String::as_mut_str`].
173    #[inline]
174    #[must_use]
175    pub fn as_mut_java_str(&mut self) -> &mut JavaStr {
176        unsafe {
177            // SAFETY: this str has semi-valid UTF-8
178            JavaStr::from_semi_utf8_unchecked_mut(&mut self.vec)
179        }
180    }
181
182    /// Tries to convert this `JavaString` to a `String`, returning an error if
183    /// it is not fully valid UTF-8, i.e. has no surrogate code points.
184    ///
185    /// ```
186    /// # use java_string::{JavaCodePoint, JavaString};
187    ///
188    /// assert_eq!(
189    ///     JavaString::from("Hello World!").into_string().unwrap(),
190    ///     "Hello World!"
191    /// );
192    /// assert_eq!(
193    ///     JavaString::from("abc\0ℝ💣").into_string().unwrap(),
194    ///     "abc\0ℝ💣"
195    /// );
196    ///
197    /// let string_with_error = JavaString::from("abc")
198    ///     + JavaString::from(JavaCodePoint::from_u32(0xd800).unwrap()).as_java_str();
199    /// assert!(string_with_error.into_string().is_err());
200    /// ```
201    pub fn into_string(self) -> Result<String, Utf8Error> {
202        run_utf8_full_validation_from_semi(self.as_bytes()).map(|_| unsafe {
203            // SAFETY: validation succeeded
204            self.into_string_unchecked()
205        })
206    }
207
208    /// # Safety
209    ///
210    /// This string must be fully valid UTF-8, i.e. have no surrogate code
211    /// points.
212    #[inline]
213    #[must_use]
214    pub unsafe fn into_string_unchecked(self) -> String {
215        // SAFETY: preconditions checked by caller
216        String::from_utf8_unchecked(self.vec)
217    }
218
219    /// See [`String::push_str`].
220    #[inline]
221    pub fn push_java_str(&mut self, string: &JavaStr) {
222        self.vec.extend_from_slice(string.as_bytes())
223    }
224
225    /// See [`String::push_str`].
226    #[inline]
227    pub fn push_str(&mut self, string: &str) {
228        self.vec.extend_from_slice(string.as_bytes())
229    }
230
231    /// See [`String::capacity`].
232    #[inline]
233    #[must_use]
234    pub fn capacity(&self) -> usize {
235        self.vec.capacity()
236    }
237
238    /// See [`String::reserve`].
239    #[inline]
240    pub fn reserve(&mut self, additional: usize) {
241        self.vec.reserve(additional)
242    }
243
244    /// See [`String::reserve_exact`].
245    #[inline]
246    pub fn reserve_exact(&mut self, additional: usize) {
247        self.vec.reserve_exact(additional)
248    }
249
250    /// See [`String::try_reserve`].
251    #[inline]
252    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
253        self.vec.try_reserve(additional)
254    }
255
256    /// See [`String::try_reserve_exact`].
257    #[inline]
258    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
259        self.vec.try_reserve_exact(additional)
260    }
261
262    /// See [`String::shrink_to_fit`].
263    #[inline]
264    pub fn shrink_to_fit(&mut self) {
265        self.vec.shrink_to_fit()
266    }
267
268    /// See [`String::shrink_to`].
269    #[inline]
270    pub fn shrink_to(&mut self, min_capacity: usize) {
271        self.vec.shrink_to(min_capacity)
272    }
273
274    /// See [`String::push`].
275    #[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    /// See [`String::push`].
286    #[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    /// See [`String::as_bytes`].
295    #[inline]
296    #[must_use]
297    pub fn as_bytes(&self) -> &[u8] {
298        &self.vec
299    }
300
301    /// See [`String::truncate`].
302    #[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    /// See [`String::pop`].
311    ///
312    /// ```
313    /// # use java_string::JavaString;
314    ///
315    /// let mut str = JavaString::from("Hello World!");
316    /// assert_eq!(str.pop().unwrap(), '!');
317    /// assert_eq!(str, "Hello World");
318    ///
319    /// let mut str = JavaString::from("東京");
320    /// assert_eq!(str.pop().unwrap(), '京');
321    /// assert_eq!(str, "東");
322    ///
323    /// assert!(JavaString::new().pop().is_none());
324    /// ```
325    #[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    /// See [`String::remove`].
336    ///
337    /// ```
338    /// # use java_string::JavaString;
339    ///
340    /// let mut str = JavaString::from("Hello World!");
341    /// assert_eq!(str.remove(5), ' ');
342    /// assert_eq!(str, "HelloWorld!");
343    ///
344    /// let mut str = JavaString::from("Hello 🦀 World!");
345    /// assert_eq!(str.remove(6), '🦀');
346    /// assert_eq!(str, "Hello  World!");
347    /// ```
348    /// ```should_panic
349    /// # use java_string::JavaString;
350    /// // Should panic
351    /// JavaString::new().remove(0);
352    /// ```
353    /// ```should_panic
354    /// # use java_string::JavaString;
355    /// // Should panic
356    /// JavaString::from("🦀").remove(1);
357    /// ```
358    #[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    /// See [`String::retain`].
379    ///
380    /// ```
381    /// # use java_string::{JavaCodePoint, JavaString};
382    ///
383    /// let mut str = JavaString::from("Hello 🦀 World!");
384    /// str.retain(|ch| !ch.is_ascii_uppercase());
385    /// assert_eq!(str, "ello 🦀 orld!");
386    /// str.retain(JavaCodePoint::is_ascii);
387    /// assert_eq!(str, "ello  orld!");
388    /// ```
389    #[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            // SAFETY: `guard.idx` is positive-or-zero and less that len so the
418            // `get_unchecked` is in bound. `self` is valid UTF-8 like string
419            // and the returned slice starts at a unicode code point so the
420            // `Chars` always return one character.
421            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                // SAFETY: `guard.idx` is in bound and `guard.del_bytes` represent the number of
435                // bytes that are erased from the string so the resulting `guard.idx -
436                // guard.del_bytes` always represent a valid unicode code point.
437                //
438                // `guard.del_bytes` >= `ch.len_utf8()`, so taking a slice with `ch.len_utf8()`
439                // len is safe.
440                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            // Point idx to the next char
449            guard.idx += ch_len;
450        }
451
452        drop(guard);
453    }
454
455    /// See [`String::insert`].
456    ///
457    /// ```
458    /// # use java_string::JavaString;
459    /// let mut s = JavaString::from("foo");
460    /// s.insert(3, 'a');
461    /// s.insert(4, 'r');
462    /// s.insert(3, 'b');
463    /// assert_eq!(s, "foobar");
464    /// ```
465    #[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    /// See [`String::insert`].
477    #[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    /// See [`String::insert_str`].
506    ///
507    /// ```
508    /// # use java_string::JavaString;
509    /// let mut s = JavaString::from("bar");
510    /// s.insert_str(0, "foo");
511    /// assert_eq!(s, "foobar");
512    /// ```
513    #[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    /// See [`String::insert_str`].
523    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    /// See [`String::as_mut_vec`].
532    ///
533    /// # Safety
534    ///
535    /// The returned `Vec` must not have invalid UTF-8 written to it, besides
536    /// surrogate pairs.
537    #[inline]
538    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
539        &mut self.vec
540    }
541
542    /// See [`String::len`].
543    #[inline]
544    #[must_use]
545    pub fn len(&self) -> usize {
546        self.vec.len()
547    }
548
549    /// See [`String::is_empty`].
550    #[inline]
551    #[must_use]
552    pub fn is_empty(&self) -> bool {
553        self.len() == 0
554    }
555
556    /// See [`String::split_off`].
557    ///
558    /// ```
559    /// # use java_string::JavaString;
560    /// let mut hello = JavaString::from("Hello World!");
561    /// let world = hello.split_off(6);
562    /// assert_eq!(hello, "Hello ");
563    /// assert_eq!(world, "World!");
564    /// ```
565    /// ```should_panic
566    /// # use java_string::JavaString;
567    /// let mut s = JavaString::from("🦀");
568    /// // Should panic
569    /// let _ = s.split_off(1);
570    /// ```
571    #[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    /// See [`String::clear`].
580    #[inline]
581    pub fn clear(&mut self) {
582        self.vec.clear();
583    }
584
585    /// See [`String::drain`].
586    ///
587    /// ```
588    /// # use java_string::JavaString;
589    ///
590    /// let mut s = JavaString::from("α is alpha, β is beta");
591    /// let beta_offset = s.find('β').unwrap_or(s.len());
592    ///
593    /// // Remove the range up until the β from the string
594    /// let t: JavaString = s.drain(..beta_offset).collect();
595    /// assert_eq!(t, "α is alpha, ");
596    /// assert_eq!(s, "β is beta");
597    ///
598    /// // A full range clears the string, like `clear()` does
599    /// s.drain(..);
600    /// assert_eq!(s, "");
601    /// ```
602    #[inline]
603    pub fn drain<R>(&mut self, range: R) -> Drain<'_>
604    where
605        R: RangeBounds<usize>,
606    {
607        // Memory safety: see String::drain
608        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        // Take out two simultaneous borrows. The &mut String won't be accessed
613        // until iteration is over, in Drop.
614        let self_ptr = self as *mut _;
615        // SAFETY: `to_range_checked` and `is_char_boundary` do the appropriate bounds
616        // checks.
617        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    /// See [`String::replace_range`].
628    ///
629    /// ```
630    /// # use java_string::JavaString;
631    ///
632    /// let mut s = JavaString::from("α is alpha, β is beta");
633    /// let beta_offset = s.find('β').unwrap_or(s.len());
634    ///
635    /// // Replace the range up until the β from the string
636    /// s.replace_range(..beta_offset, "Α is capital alpha; ");
637    /// assert_eq!(s, "Α is capital alpha; β is beta");
638    /// ```
639    /// ```should_panic
640    /// # use java_string::JavaString;
641    /// let mut s = JavaString::from("α is alpha, β is beta");
642    /// // Should panic
643    /// s.replace_range(..1, "Α is capital alpha; ");
644    /// ```
645    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    /// See [`String::replace_range`].
653    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    /// See [`String::into_boxed_str`].
674    #[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    /// See [`String::leak`].
682    #[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            // SAFETY: value is valid UTF-8
883            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            // SAFETY: we're encoding into semi-valid UTF-8
998            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            // Use Vec::drain. "Reaffirm" the bounds checks to avoid
1344            // panic code being inserted again.
1345            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<'_> {}