Skip to content

Commit 088f03c

Browse files
committed
Fixed to support non-ascii strings
1 parent 51efc6f commit 088f03c

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

src/string.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ impl<const N: usize> String<N> {
255255
Some(ch)
256256
}
257257

258-
/// Removes a [`u8`] from this `String` at a byte position and returns it.
258+
/// Removes a [`char`] from this `String` at a byte position and returns it.
259259
///
260260
/// Note: Because this shifts over the remaining elements, it has a
261261
/// worst-case performance of *O*(*n*).
@@ -274,13 +274,28 @@ impl<const N: usize> String<N> {
274274
///
275275
/// let mut s: String<8> = String::from("foo");
276276
///
277-
/// assert_eq!(s.remove(0), b'f');
278-
/// assert_eq!(s.remove(1), b'o');
279-
/// assert_eq!(s.remove(0), b'o');
277+
/// assert_eq!(s.remove(0), 'f');
278+
/// assert_eq!(s.remove(1), 'o');
279+
/// assert_eq!(s.remove(0), 'o');
280280
/// ```
281281
#[inline]
282-
pub fn remove(&mut self, index: usize) -> u8 {
283-
self.vec.remove(index)
282+
pub fn remove(&mut self, index: usize) -> char {
283+
let ch = match self[index..].chars().next() {
284+
Some(ch) => ch,
285+
None => panic!("cannot remove a char from the end of a string"),
286+
};
287+
288+
let next = index + ch.len_utf8();
289+
let len = self.len();
290+
unsafe {
291+
core::ptr::copy(
292+
self.vec.as_ptr().add(next),
293+
self.vec.as_mut_ptr().add(index),
294+
len - next,
295+
);
296+
self.vec.set_len(len - (next - index));
297+
}
298+
ch
284299
}
285300

286301
/// Truncates this `String`, removing all contents.
@@ -740,7 +755,23 @@ mod tests {
740755
#[test]
741756
fn remove() {
742757
let mut s: String<8> = String::from("foo");
743-
assert_eq!(b'f', s.remove(0));
744-
assert_eq!("oo", s.as_str());
758+
assert_eq!(s.remove(0), 'f');
759+
assert_eq!(s.as_str(), "oo");
760+
}
761+
762+
#[test]
763+
fn remove_uenc() {
764+
let mut s: String<8> = String::from("ĝėēƶ");
765+
assert_eq!(s.remove(2), 'ė');
766+
assert_eq!(s.remove(2), 'ē');
767+
assert_eq!(s.remove(2), 'ƶ');
768+
assert_eq!(s.as_str(), "ĝ");
769+
}
770+
771+
#[test]
772+
fn remove_uenc_combo_characters() {
773+
let mut s: String<8> = String::from("héy");
774+
assert_eq!(s.remove(2), '\u{0301}');
775+
assert_eq!(s.as_str(), "hey");
745776
}
746777
}

0 commit comments

Comments
 (0)