abi_stable/std_types/string.rs
1//! Contains an ffi-safe equivalent of `std::string::String`.
2
3use std::{
4 borrow::{Borrow, Cow},
5 fmt::{self, Display, Formatter},
6 iter::{FromIterator, FusedIterator},
7 marker::PhantomData,
8 ops::{Deref, Index, Range},
9 ptr,
10 str::{from_utf8, Chars, FromStr, Utf8Error},
11 string::FromUtf16Error,
12};
13
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15
16#[allow(unused_imports)]
17use core_extensions::{SelfOps, SliceExt, StringExt};
18
19use crate::std_types::{RStr, RVec};
20
21mod iters;
22
23#[cfg(test)]
24// #[cfg(all(test, not(feature = "only_new_tests")))]
25mod tests;
26
27pub use self::iters::{Drain, IntoIter};
28
29/// Ffi-safe equivalent of `std::string::String`.
30///
31/// # Example
32///
33/// This defines a function returning the last word of an `RString`.
34///
35/// ```
36/// use abi_stable::{sabi_extern_fn, std_types::RString};
37///
38/// #[sabi_extern_fn]
39/// fn first_word(phrase: RString) -> RString {
40/// match phrase.split_whitespace().next_back() {
41/// Some(x) => x.into(),
42/// None => RString::new(),
43/// }
44/// }
45///
46///
47/// ```
48///
49#[derive(Clone)]
50#[repr(C)]
51#[derive(StableAbi)]
52pub struct RString {
53 inner: RVec<u8>,
54}
55
56impl RString {
57 /// Creates a new, empty RString.
58 ///
59 /// # Example
60 ///
61 /// ```
62 /// use abi_stable::std_types::RString;
63 ///
64 /// let str = RString::new();
65 ///
66 /// assert_eq!(&str[..], "");
67 ///
68 /// ```
69 pub const fn new() -> Self {
70 Self::NEW
71 }
72
73 const NEW: Self = Self { inner: RVec::new() };
74
75 /// Creates a new,
76 /// empty RString with the capacity for `cap` bytes without reallocating.
77 ///
78 /// # Example
79 ///
80 /// ```
81 /// use abi_stable::std_types::RString;
82 ///
83 /// let str = RString::with_capacity(10);
84 ///
85 /// assert_eq!(&str[..], "");
86 /// assert_eq!(str.capacity(), 10);
87 ///
88 /// ```
89 pub fn with_capacity(cap: usize) -> Self {
90 String::with_capacity(cap).into()
91 }
92
93 /// For slicing into `RStr`s.
94 ///
95 /// This is an inherent method instead of an implementation of the
96 /// `std::ops::Index` trait because it does not return a reference.
97 ///
98 /// # Example
99 ///
100 /// ```
101 /// use abi_stable::std_types::{RStr, RString};
102 ///
103 /// let str = RString::from("What is that.");
104 ///
105 /// assert_eq!(str.slice(..), RStr::from("What is that."));
106 /// assert_eq!(str.slice(..4), RStr::from("What"));
107 /// assert_eq!(str.slice(4..), RStr::from(" is that."));
108 /// assert_eq!(str.slice(4..7), RStr::from(" is"));
109 ///
110 /// ```
111 #[inline]
112 #[allow(clippy::needless_lifetimes)]
113 pub fn slice<'a, I>(&'a self, i: I) -> RStr<'a>
114 where
115 str: Index<I, Output = str>,
116 {
117 (&self[i]).into()
118 }
119
120 conditionally_const! {
121 feature = "rust_1_64"
122 /// Creates a `&str` with access to all the characters of the `RString`.
123 ///
124 ;
125 ///
126 /// # Example
127 ///
128 /// ```
129 /// use abi_stable::std_types::RString;
130 ///
131 /// let str = "What is that.";
132 /// assert_eq!(RString::from(str).as_str(), str);
133 ///
134 /// ```
135 #[inline]
136 pub fn as_str(&self) -> &str {
137 unsafe { std::str::from_utf8_unchecked(self.inner.as_slice()) }
138 }
139 }
140
141 /// Creates an `RStr<'_>` with access to all the characters of the `RString`.
142 ///
143 /// # Example
144 ///
145 /// ```
146 /// use abi_stable::std_types::{RStr, RString};
147 ///
148 /// let str = "What is that.";
149 /// assert_eq!(RString::from(str).as_rstr(), RStr::from(str),);
150 ///
151 /// ```
152 #[inline]
153 pub const fn as_rstr(&self) -> RStr<'_> {
154 unsafe { RStr::from_raw_parts(self.as_ptr(), self.len()) }
155 }
156
157 /// Returns the current length (in bytes) of the RString.
158 ///
159 /// # Example
160 ///
161 /// ```
162 /// use abi_stable::std_types::RString;
163 ///
164 /// assert_eq!(RString::from("").len(), 0);
165 /// assert_eq!(RString::from("a").len(), 1);
166 /// assert_eq!(RString::from("Regular").len(), 7);
167 ///
168 /// ```
169 #[inline]
170 pub const fn len(&self) -> usize {
171 self.inner.len()
172 }
173
174 /// Returns whether the RString is empty.
175 ///
176 /// # Example
177 ///
178 /// ```
179 /// use abi_stable::std_types::RString;
180 ///
181 /// assert_eq!(RString::from("").is_empty(), true);
182 /// assert_eq!(RString::from("a").is_empty(), false);
183 /// assert_eq!(RString::from("Regular").is_empty(), false);
184 ///
185 /// ```
186 #[inline]
187 pub const fn is_empty(&self) -> bool {
188 self.inner.is_empty()
189 }
190
191 /// Gets a raw pointer to the start of this RString's buffer.
192 pub const fn as_ptr(&self) -> *const u8 {
193 self.inner.as_ptr()
194 }
195
196 /// Returns the current capacity (in bytes) of the RString.
197 ///
198 /// # Example
199 ///
200 /// ```
201 /// use abi_stable::std_types::RString;
202 ///
203 /// let mut str = RString::with_capacity(13);
204 ///
205 /// assert_eq!(str.capacity(), 13);
206 ///
207 /// str.push_str("What is that.");
208 /// assert_eq!(str.capacity(), 13);
209 ///
210 /// str.push(' ');
211 /// assert_ne!(str.capacity(), 13);
212 ///
213 /// ```
214 #[inline]
215 pub const fn capacity(&self) -> usize {
216 self.inner.capacity()
217 }
218
219 /// An unchecked conversion from a `RVec<u8>` to an `RString`.
220 ///
221 /// # Safety
222 ///
223 /// This has the same safety requirements as
224 /// [`String::from_utf8_unchecked`
225 /// ](https://doc.rust-lang.org/std/string/struct.String.html#method.from_utf8_unchecked).
226 ///
227 /// # Examples
228 ///
229 /// ```
230 /// use abi_stable::std_types::{RString, RVec};
231 ///
232 /// let bytes = RVec::from("hello".as_bytes());
233 ///
234 /// unsafe {
235 /// assert_eq!(RString::from_utf8_unchecked(bytes).as_str(), "hello");
236 /// }
237 ///
238 /// ```
239 #[inline]
240 pub const unsafe fn from_utf8_unchecked(vec: RVec<u8>) -> Self {
241 RString { inner: vec }
242 }
243
244 /// Converts the `vec` vector of bytes to an `RString`.
245 ///
246 /// # Errors
247 ///
248 /// This returns a `Err(FromUtf8Error{..})` if `vec` is not valid utf-8.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use abi_stable::std_types::{RString, RVec};
254 ///
255 /// let bytes_ok = RVec::from("hello".as_bytes());
256 /// let bytes_err = RVec::from(vec![255]);
257 ///
258 /// assert_eq!(
259 /// RString::from_utf8(bytes_ok).unwrap(),
260 /// RString::from("hello")
261 /// );
262 /// assert!(RString::from_utf8(bytes_err).is_err());
263 ///
264 /// ```
265 pub fn from_utf8<V>(vec: V) -> Result<Self, FromUtf8Error>
266 where
267 V: Into<RVec<u8>>,
268 {
269 let vec = vec.into();
270 match from_utf8(&vec) {
271 Ok(..) => Ok(RString { inner: vec }),
272 Err(e) => Err(FromUtf8Error {
273 bytes: vec,
274 error: e,
275 }),
276 }
277 }
278
279 /// Decodes a utf-16 encoded `&[u16]` to an `RString`.
280 ///
281 /// # Errors
282 ///
283 /// This returns a `Err(::std::string::FromUtf16Error{..})`
284 /// if `vec` is not valid utf-8.
285 ///
286 /// # Example
287 ///
288 /// ```
289 /// use abi_stable::std_types::RString;
290 ///
291 /// let str = "What the 😈.";
292 /// let str_utf16 = str.encode_utf16().collect::<Vec<u16>>();
293 ///
294 /// assert_eq!(RString::from_utf16(&str_utf16).unwrap(), RString::from(str),);
295 /// ```
296 pub fn from_utf16(s: &[u16]) -> Result<Self, FromUtf16Error> {
297 String::from_utf16(s).map(From::from)
298 }
299
300 /// Cheap conversion of this `RString` to a `RVec<u8>`
301 ///
302 /// # Example
303 ///
304 /// ```
305 /// use abi_stable::std_types::{RString, RVec};
306 ///
307 /// let bytes = RVec::from("hello".as_bytes());
308 /// let str = RString::from("hello");
309 ///
310 /// assert_eq!(str.into_bytes(), bytes);
311 ///
312 /// ```
313 #[allow(clippy::missing_const_for_fn)]
314 pub fn into_bytes(self) -> RVec<u8> {
315 self.inner
316 }
317
318 /// Converts this `RString` to a `String`.
319 ///
320 /// # Allocation
321 ///
322 /// If this is invoked outside of the dynamic library/binary that created it,
323 /// it will allocate a new `String` and move the data into it.
324 ///
325 /// # Example
326 ///
327 /// ```
328 /// use abi_stable::std_types::RString;
329 ///
330 /// let std_str = String::from("hello");
331 /// let str = RString::from("hello");
332 ///
333 /// assert_eq!(str.into_string(), std_str);
334 ///
335 /// ```
336 pub fn into_string(self) -> String {
337 unsafe { String::from_utf8_unchecked(self.inner.into_vec()) }
338 }
339 /// Copies the `RString` into a `String`.
340 ///
341 /// # Example
342 ///
343 /// ```
344 /// use abi_stable::std_types::RString;
345 ///
346 /// assert_eq!(RString::from("world").to_string(), String::from("world"));
347 ///
348 /// ```
349 #[allow(clippy::inherent_to_string_shadow_display)]
350 pub fn to_string(&self) -> String {
351 self.as_str().to_string()
352 }
353
354 /// Reserves `Ã dditional` additional capacity for any extra string data.
355 /// This may reserve more than necessary for the additional capacity.
356 ///
357 /// # Example
358 ///
359 /// ```
360 /// use abi_stable::std_types::RString;
361 ///
362 /// let mut str = RString::new();
363 ///
364 /// str.reserve(10);
365 /// assert!(str.capacity() >= 10);
366 ///
367 /// ```
368 pub fn reserve(&mut self, additional: usize) {
369 self.inner.reserve(additional);
370 }
371
372 /// Shrinks the capacity of the RString to match its length.
373 ///
374 /// # Example
375 ///
376 /// ```
377 /// use abi_stable::std_types::RString;
378 ///
379 /// let mut str = RString::with_capacity(100);
380 /// str.push_str("nope");
381 /// str.shrink_to_fit();
382 /// assert_eq!(str.capacity(), 4);
383 ///
384 /// ```
385 pub fn shrink_to_fit(&mut self) {
386 self.inner.shrink_to_fit()
387 }
388
389 /// Reserves `Ã dditional` additional capacity for any extra string data.
390 ///
391 /// Prefer using `reserve` for most situations.
392 ///
393 /// # Example
394 ///
395 /// ```
396 /// use abi_stable::std_types::RString;
397 ///
398 /// let mut str = RString::new();
399 ///
400 /// str.reserve_exact(10);
401 /// assert_eq!(str.capacity(), 10);
402 ///
403 /// ```
404 pub fn reserve_exact(&mut self, additional: usize) {
405 self.inner.reserve_exact(additional);
406 }
407
408 /// Appends `ch` at the end of this RString.
409 ///
410 /// # Example
411 ///
412 /// ```
413 /// use abi_stable::std_types::RString;
414 ///
415 /// let mut str = RString::new();
416 ///
417 /// str.push('O');
418 /// str.push('O');
419 /// str.push('P');
420 ///
421 /// assert_eq!(str.as_str(), "OOP");
422 ///
423 /// ```
424 pub fn push(&mut self, ch: char) {
425 match ch.len_utf8() {
426 1 => self.inner.push(ch as u8),
427 _ => self.push_str(ch.encode_utf8(&mut [0; 4])),
428 }
429 }
430
431 /// Appends `str` at the end of this RString.
432 ///
433 /// # Example
434 ///
435 /// ```
436 /// use abi_stable::std_types::RString;
437 ///
438 /// let mut str = RString::new();
439 ///
440 /// str.push_str("green ");
441 /// str.push_str("frog");
442 ///
443 /// assert_eq!(str.as_str(), "green frog");
444 ///
445 /// ```
446 pub fn push_str(&mut self, str: &str) {
447 self.inner.extend_from_copy_slice(str.as_bytes());
448 }
449
450 /// Removes the last character,
451 /// returns `Some(_)` if this `RString` is not empty,
452 /// otherwise returns `None`.
453 ///
454 /// # Example
455 ///
456 /// ```
457 /// use abi_stable::std_types::{RString, RVec};
458 ///
459 /// let mut str = RString::from("yep");
460 ///
461 /// assert_eq!(str.pop(), Some('p'));
462 /// assert_eq!(str.pop(), Some('e'));
463 /// assert_eq!(str.pop(), Some('y'));
464 /// assert_eq!(str.pop(), None);
465 ///
466 /// ```
467 pub fn pop(&mut self) -> Option<char> {
468 // literal copy-paste of std, so if this is wrong std is wrong.
469
470 let ch = self.chars().rev().next()?;
471 let newlen = self.len() - ch.len_utf8();
472 unsafe {
473 self.inner.set_len(newlen);
474 }
475 Some(ch)
476 }
477
478 /// Removes and returns the character starting at the `idx` byte position,
479 ///
480 /// # Panics
481 ///
482 /// Panics if the index is out of bounds or if it is not on a char boundary.
483 ///
484 /// # Example
485 ///
486 /// ```
487 /// use abi_stable::std_types::{RString, RVec};
488 ///
489 /// let mut str = RString::from("Galileo");
490 ///
491 /// assert_eq!(str.remove(3), 'i');
492 /// assert_eq!(str.as_str(), "Galleo");
493 ///
494 /// assert_eq!(str.remove(4), 'e');
495 /// assert_eq!(str.as_str(), "Gallo");
496 ///
497 /// ```
498 pub fn remove(&mut self, idx: usize) -> char {
499 // literal copy-paste of std, so if this is wrong std is wrong.
500
501 let ch = match self[idx..].chars().next() {
502 Some(ch) => ch,
503 None => panic!("cannot remove a char beyond the end of a string"),
504 };
505
506 let next = idx + ch.len_utf8();
507 let len = self.len();
508 unsafe {
509 let ptr = self.inner.as_mut_ptr();
510 ptr::copy(ptr.add(next), ptr.add(idx), len - next);
511 self.inner.set_len(len - (next - idx));
512 }
513 ch
514 }
515
516 /// Insert the `ch` character at the `ìdx` byte position.
517 ///
518 /// # Panics
519 ///
520 /// Panics if the index is out of bounds or if it is not on a char boundary.
521 ///
522 /// # Example
523 ///
524 /// ```
525 /// use abi_stable::std_types::{RString, RVec};
526 ///
527 /// let mut str = RString::from("Cap");
528 ///
529 /// str.insert(1, 'r');
530 /// assert_eq!(str.as_str(), "Crap");
531 ///
532 /// str.insert(4, 'p');
533 /// assert_eq!(str.as_str(), "Crapp");
534 ///
535 /// str.insert(5, 'y');
536 /// assert_eq!(str.as_str(), "Crappy");
537 ///
538 /// ```
539 pub fn insert(&mut self, idx: usize, ch: char) {
540 let mut bits = [0; 4];
541 let str_ = ch.encode_utf8(&mut bits);
542
543 self.insert_str(idx, str_);
544 }
545
546 /// Insert the `string` at the `ìdx` byte position.
547 ///
548 /// # Panics
549 ///
550 /// Panics if the index is out of bounds or if it is not on a char boundary.
551 ///
552 /// # Example
553 ///
554 /// ```
555 /// use abi_stable::std_types::{RString, RVec};
556 ///
557 /// let mut str = RString::from("rust");
558 ///
559 /// str.insert_str(0, "T");
560 /// assert_eq!(str.as_str(), "Trust");
561 ///
562 /// str.insert_str(5, " the source");
563 /// assert_eq!(str.as_str(), "Trust the source");
564 ///
565 /// str.insert_str(5, " the types in");
566 /// assert_eq!(str.as_str(), "Trust the types in the source");
567 ///
568 /// ```
569 pub fn insert_str(&mut self, idx: usize, string: &str) {
570 // literal copy-paste of std, so if this is wrong std is wrong.
571
572 assert!(self.is_char_boundary(idx));
573
574 unsafe {
575 self.insert_bytes(idx, string.as_bytes());
576 }
577 }
578
579 unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
580 let len = self.len();
581 let amt = bytes.len();
582 self.inner.reserve(amt);
583
584 let ptr = self.inner.as_mut_ptr();
585 unsafe {
586 ptr::copy(ptr.add(idx), ptr.add(idx + amt), len - idx);
587 ptr::copy(bytes.as_ptr(), self.inner.as_mut_ptr().add(idx), amt);
588 self.inner.set_len(len + amt);
589 }
590 }
591
592 /// Retains only the characters that satisfy the `pred` predicate
593 ///
594 /// This means that a character will be removed if `pred(that_character)`
595 /// returns false.
596 ///
597 /// # Example
598 ///
599 /// ```
600 /// use abi_stable::std_types::{RString, RVec};
601 ///
602 /// {
603 /// let mut str = RString::from("There were 10 people.");
604 /// str.retain(|c| !c.is_numeric());
605 /// assert_eq!(str.as_str(), "There were people.");
606 /// }
607 /// {
608 /// let mut str = RString::from("There were 10 people.");
609 /// str.retain(|c| !c.is_whitespace());
610 /// assert_eq!(str.as_str(), "Therewere10people.");
611 /// }
612 /// {
613 /// let mut str = RString::from("There were 10 people.");
614 /// str.retain(|c| c.is_numeric());
615 /// assert_eq!(str.as_str(), "10");
616 /// }
617 ///
618 /// ```
619 #[inline]
620 pub fn retain<F>(&mut self, mut pred: F)
621 where
622 F: FnMut(char) -> bool,
623 {
624 let len = self.len();
625 let mut del_bytes = 0;
626 let mut idx = 0;
627
628 unsafe {
629 self.inner.set_len(0);
630 }
631
632 let start = self.inner.as_mut_ptr();
633
634 while idx < len {
635 let curr = unsafe { start.add(idx) };
636
637 let ch = unsafe {
638 RStr::from_raw_parts(curr, len - idx)
639 .chars()
640 .next()
641 .unwrap()
642 };
643 let ch_len = ch.len_utf8();
644
645 if !pred(ch) {
646 del_bytes += ch_len;
647 } else if del_bytes > 0 {
648 unsafe {
649 ptr::copy(curr, curr.sub(del_bytes), ch_len);
650 }
651 }
652
653 // Point idx to the next char
654 idx += ch_len;
655 }
656
657 unsafe {
658 self.inner.set_len(len - del_bytes);
659 }
660 }
661
662 /// Turns this into an empty RString, keeping the same allocated buffer.
663 ///
664 /// # Example
665 ///
666 /// ```
667 /// use abi_stable::std_types::{RString, RVec};
668 ///
669 /// let mut str = RString::from("Nurse");
670 ///
671 /// assert_eq!(str.as_str(), "Nurse");
672 ///
673 /// str.clear();
674 ///
675 /// assert_eq!(str.as_str(), "");
676 ///
677 /// ```
678 pub fn clear(&mut self) {
679 self.inner.clear();
680 }
681}
682
683/// Returns an empty RString
684impl Default for RString {
685 fn default() -> Self {
686 String::new().into()
687 }
688}
689
690////////////////////
691
692deref_coerced_impl_cmp_traits! {
693 RString;
694 coerce_to = str,
695 [
696 String,
697 str,
698 &str,
699 RStr<'_>,
700 std::borrow::Cow<'_, str>,
701 crate::std_types::RCowStr<'_>,
702 ]
703}
704
705////////////////////
706
707impl_into_rust_repr! {
708 impl Into<String> for RString {
709 fn(this){
710 this.into_string()
711 }
712 }
713}
714
715impl<'a> From<RString> for Cow<'a, str> {
716 fn from(this: RString) -> Cow<'a, str> {
717 this.into_string().piped(Cow::Owned)
718 }
719}
720
721impl From<&str> for RString {
722 fn from(this: &str) -> Self {
723 this.to_owned().into()
724 }
725}
726
727impl_from_rust_repr! {
728 impl From<String> for RString {
729 fn(this){
730 RString {
731 inner: this.into_bytes().into(),
732 }
733 }
734 }
735}
736
737impl<'a> From<Cow<'a, str>> for RString {
738 fn from(this: Cow<'a, str>) -> Self {
739 this.into_owned().into()
740 }
741}
742
743////////////////////
744
745impl FromStr for RString {
746 type Err = <String as FromStr>::Err;
747
748 fn from_str(s: &str) -> Result<Self, Self::Err> {
749 s.parse::<String>().map(RString::from)
750 }
751}
752
753////////////////////
754
755impl Borrow<str> for RString {
756 fn borrow(&self) -> &str {
757 self
758 }
759}
760
761impl AsRef<str> for RString {
762 fn as_ref(&self) -> &str {
763 self
764 }
765}
766
767impl AsRef<[u8]> for RString {
768 fn as_ref(&self) -> &[u8] {
769 self.as_bytes()
770 }
771}
772
773////////////////////
774
775impl Deref for RString {
776 type Target = str;
777
778 #[inline]
779 fn deref(&self) -> &Self::Target {
780 self.as_str()
781 }
782}
783
784impl Display for RString {
785 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
786 Display::fmt(self.as_str(), f)
787 }
788}
789
790impl fmt::Write for RString {
791 #[inline]
792 fn write_str(&mut self, s: &str) -> fmt::Result {
793 self.push_str(s);
794 Ok(())
795 }
796
797 #[inline]
798 fn write_char(&mut self, c: char) -> fmt::Result {
799 self.push(c);
800 Ok(())
801 }
802}
803
804shared_impls! {
805 mod = string_impls
806 new_type = RString[][],
807 original_type = str,
808}
809
810impl<'de> Deserialize<'de> for RString {
811 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
812 where
813 D: Deserializer<'de>,
814 {
815 String::deserialize(deserializer).map(From::from)
816 }
817}
818
819impl Serialize for RString {
820 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
821 where
822 S: Serializer,
823 {
824 self.as_str().serialize(serializer)
825 }
826}
827
828//////////////////////////////////////////////////////
829
830impl RString {
831 /// Creates an iterator that yields the chars in the `range`,
832 /// removing the characters in that range in the process.
833 ///
834 /// # Panic
835 ///
836 /// Panics if the start or end of the range are not on a on a char boundary,
837 /// or if either are out of bounds.
838 ///
839 /// # Example
840 ///
841 /// ```
842 /// use abi_stable::std_types::RString;
843 ///
844 /// let orig = "Not a single way";
845 ///
846 /// {
847 /// let mut str = RString::from(orig);
848 /// assert_eq!(str.drain(..).collect::<String>(), orig,);
849 /// assert_eq!(str.as_str(), "");
850 /// }
851 /// {
852 /// let mut str = RString::from(orig);
853 /// assert_eq!(str.drain(..4).collect::<String>(), "Not ",);
854 /// assert_eq!(str.as_str(), "a single way");
855 /// }
856 /// {
857 /// let mut str = RString::from(orig);
858 /// assert_eq!(str.drain(4..).collect::<String>(), "a single way",);
859 /// assert_eq!(str.as_str(), "Not ");
860 /// }
861 /// {
862 /// let mut str = RString::from(orig);
863 /// assert_eq!(str.drain(4..13).collect::<String>(), "a single ",);
864 /// assert_eq!(str.as_str(), "Not way");
865 /// }
866 ///
867 /// ```
868 pub fn drain<I>(&mut self, range: I) -> Drain<'_>
869 where
870 str: Index<I, Output = str>,
871 {
872 let string = self as *mut _;
873 let slic_ = &(*self)[range];
874 let start = self.offset_of_slice(slic_);
875 let end = start + slic_.len();
876 Drain {
877 string,
878 removed: start..end,
879 iter: slic_.chars(),
880 variance: PhantomData,
881 }
882 }
883}
884
885impl IntoIterator for RString {
886 type Item = char;
887
888 type IntoIter = IntoIter;
889
890 fn into_iter(self) -> IntoIter {
891 unsafe {
892 // Make sure that the buffer is not deallocated as long as the iterator is accessible.
893 let text: &'static str = &*(&*self as *const str);
894 IntoIter {
895 iter: text.chars(),
896 _buf: self,
897 }
898 }
899 }
900}
901
902impl FromIterator<char> for RString {
903 fn from_iter<I>(iter: I) -> Self
904 where
905 I: IntoIterator<Item = char>,
906 {
907 iter.piped(String::from_iter).piped(Self::from)
908 }
909}
910
911impl<'a> FromIterator<&'a char> for RString {
912 fn from_iter<I>(iter: I) -> Self
913 where
914 I: IntoIterator<Item = &'a char>,
915 {
916 iter.piped(String::from_iter).piped(Self::from)
917 }
918}
919
920//////////////////////////////////////////////////////
921
922/// Error that happens when attempting to convert an `RVec<u8>` into an `RString`.
923///
924/// # Example
925///
926/// ```
927/// use abi_stable::std_types::RString;
928///
929/// let err = RString::from_utf8(vec![0, 0, 0, 255]).unwrap_err();
930///
931/// assert_eq!(err.as_bytes(), &[0, 0, 0, 255])
932///
933/// ```
934#[derive(Debug)]
935pub struct FromUtf8Error {
936 bytes: RVec<u8>,
937 error: Utf8Error,
938}
939
940#[allow(clippy::missing_const_for_fn)]
941impl FromUtf8Error {
942 /// Unwraps this error into the bytes that failed to be converted into an `RString`.
943 ///
944 /// # Example
945 ///
946 /// ```
947 /// use abi_stable::std_types::{RString, RVec};
948 ///
949 /// let bytes: RVec<u8> = vec![72, 111, 95, 95, 95, 95, 95, 99, 107, 255].into();
950 ///
951 /// let err = RString::from_utf8(bytes.clone()).unwrap_err();
952 ///
953 /// assert_eq!(err.into_bytes(), bytes);
954 ///
955 /// ```
956 pub fn into_bytes(self) -> RVec<u8> {
957 self.bytes
958 }
959 /// Gets access to the bytes that failed to be converted into an `RString`.
960 ///
961 /// # Example
962 ///
963 /// ```
964 /// use abi_stable::std_types::RString;
965 ///
966 /// let bytes = vec![99, 114, 121, 115, 116, 97, 108, 255];
967 ///
968 /// let err = RString::from_utf8(bytes.clone()).unwrap_err();
969 ///
970 /// assert_eq!(err.as_bytes(), &bytes[..]);
971 ///
972 /// ```
973 pub fn as_bytes(&self) -> &[u8] {
974 &self.bytes
975 }
976
977 /// Gets a Utf8Error with information about the conversion error.
978 ///
979 /// # Example
980 ///
981 /// ```
982 /// use abi_stable::std_types::RString;
983 ///
984 /// let err = RString::from_utf8(vec![0, 0, 255]).unwrap_err();
985 ///
986 /// assert_eq!(err.error().valid_up_to(), 2);
987 ///
988 /// ```
989 pub fn error(&self) -> Utf8Error {
990 self.error
991 }
992}
993
994impl fmt::Display for FromUtf8Error {
995 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
996 fmt::Display::fmt(&self.error, f)
997 }
998}
999
1000impl std::error::Error for FromUtf8Error {}