@@ -68,71 +68,6 @@ pub type String<const N: usize> = StringInner<OwnedVecStorage<u8, N>>;
6868/// A dynamic capacity [`String`](https://doc.rust-lang.org/std/string/struct.String.html).
6969pub type StringView = StringInner < ViewVecStorage < u8 > > ;
7070
71- impl StringView {
72- /// Removes the specified range from the string in bulk, returning all
73- /// removed characters as an iterator.
74- ///
75- /// The returned iterator keeps a mutable borrow on the string to optimize
76- /// its implementation.
77- ///
78- /// # Panics
79- ///
80- /// Panics if the starting point or end point do not lie on a [`char`]
81- /// boundary, or if they're out of bounds.
82- ///
83- /// # Leaking
84- ///
85- /// If the returned iterator goes out of scope without being dropped (due to
86- /// [`core::mem::forget`], for example), the string may still contain a copy
87- /// of any drained characters, or may have lost characters arbitrarily,
88- /// including characters outside the range.
89- ///
90- /// # Examples
91- ///
92- /// ```
93- /// use heapless::String;
94- ///
95- /// let mut s = String::<32>::try_from("α is alpha, β is beta").unwrap();
96- /// let beta_offset = s.find('β').unwrap_or(s.len());
97- ///
98- /// // Remove the range up until the β from the string
99- /// let t: String<32> = s.drain(..beta_offset).collect();
100- /// assert_eq!(t, "α is alpha, ");
101- /// assert_eq!(s, "β is beta");
102- ///
103- /// // A full range clears the string, like `clear()` does
104- /// s.drain(..);
105- /// assert_eq!(s, "");
106- /// ```
107- pub fn drain < R > ( & mut self , range : R ) -> Drain < ' _ >
108- where
109- R : RangeBounds < usize > ,
110- {
111- // Memory safety
112- //
113- // The `String` version of `Drain` does not have the memory safety issues
114- // of the `Vec` version. The data is just plain bytes.
115- // Because the range removal happens in `Drop`, if the `Drain` iterator is leaked,
116- // the removal will not happen.
117- let Range { start, end } = crate :: slice:: range ( range, ..self . len ( ) ) ;
118- assert ! ( self . is_char_boundary( start) ) ;
119- assert ! ( self . is_char_boundary( end) ) ;
120-
121- // Take out two simultaneous borrows. The &mut String won't be accessed
122- // until iteration is over, in Drop.
123- let self_ptr = self as * mut _ ;
124- // SAFETY: `slice::range` and `is_char_boundary` do the appropriate bounds checks.
125- let chars_iter = unsafe { self . get_unchecked ( start..end) } . chars ( ) ;
126-
127- Drain {
128- start,
129- end,
130- iter : chars_iter,
131- string : self_ptr,
132- }
133- }
134- }
135-
13671impl < const N : usize > String < N > {
13772 /// Constructs a new, empty `String` with a fixed capacity of `N` bytes.
13873 ///
@@ -275,7 +210,9 @@ impl<const N: usize> String<N> {
275210 pub fn into_bytes ( self ) -> Vec < u8 , N > {
276211 self . vec
277212 }
213+ }
278214
215+ impl < S : VecStorage < u8 > + ?Sized > StringInner < S > {
279216 /// Removes the specified range from the string in bulk, returning all
280217 /// removed characters as an iterator.
281218 ///
@@ -315,11 +252,30 @@ impl<const N: usize> String<N> {
315252 where
316253 R : RangeBounds < usize > ,
317254 {
318- self . as_mut_view ( ) . drain ( range)
255+ // Memory safety
256+ //
257+ // The `String` version of `Drain` does not have the memory safety issues
258+ // of the `Vec` version. The data is just plain bytes.
259+ // Because the range removal happens in `Drop`, if the `Drain` iterator is leaked,
260+ // the removal will not happen.
261+ let Range { start, end } = crate :: slice:: range ( range, ..self . len ( ) ) ;
262+ assert ! ( self . is_char_boundary( start) ) ;
263+ assert ! ( self . is_char_boundary( end) ) ;
264+
265+ // Take out two simultaneous borrows. The &mut String won't be accessed
266+ // until iteration is over, in Drop.
267+ let self_ptr = self . as_mut_view ( ) as * mut _ ;
268+ // SAFETY: `slice::range` and `is_char_boundary` do the appropriate bounds checks.
269+ let chars_iter = unsafe { self . get_unchecked ( start..end) } . chars ( ) ;
270+
271+ Drain {
272+ start,
273+ end,
274+ iter : chars_iter,
275+ string : self_ptr,
276+ }
319277 }
320- }
321278
322- impl < S : VecStorage < u8 > + ?Sized > StringInner < S > {
323279 /// Get a reference to the `String`, erasing the `N` const-generic.
324280 ///
325281 ///
0 commit comments