Skip to main content

ByteStr

Struct ByteStr 

Source
#[repr(transparent)]
pub struct ByteStr(pub [u8]);
🔬This is a nightly-only experimental API. (bstr #134915)
Expand description

A wrapper for &[u8] representing a human-readable string that’s conventionally, but not always, UTF-8.

Unlike &str, this type permits non-UTF-8 contents, making it suitable for user input, non-native filenames (as Path only supports native filenames), and other applications that need to round-trip whatever data the user provides.

For an owned, growable byte string buffer, use ByteString.

ByteStr implements Deref to [u8], so all methods available on [u8] are available on ByteStr.

§Representation

A &ByteStr has the same representation as a &str. That is, a &ByteStr is a wide pointer which includes a pointer to some bytes and a length.

§Trait implementations

The ByteStr type has a number of trait implementations, and in particular, defines equality and comparisons between &ByteStr, &str, and &[u8], for convenience.

The Debug implementation for ByteStr shows its bytes as a normal string, with invalid UTF-8 presented as hex escape sequences.

The Display implementation behaves as if the ByteStr were first lossily converted to a str, with invalid UTF-8 presented as the Unicode replacement character (�).

Tuple Fields§

§0: [u8]
🔬This is a nightly-only experimental API. (bstr #134915)

Methods from Deref<Target = [u8]>§

1.23.0 · Source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

An empty slice returns true.

1.23.0 · Source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), but without allocating and copying temporaries.

1.60.0 · Source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, treating it as an ASCII string.

§Examples
let s = b"0\t\r\n'\"\\\x9d";
let escaped = s.escape_ascii().to_string();
assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
1.0.0 · Source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

§Examples
let a = [1, 2, 3];
assert_eq!(a.len(), 3);
1.0.0 · Source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

§Examples
let a = [1, 2, 3];
assert!(!a.is_empty());

let b: &[i32] = &[];
assert!(b.is_empty());
1.0.0 · Source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

§Examples
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());

let w: &[i32] = &[];
assert_eq!(None, w.first());
1.0.0 · Source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the first element of the slice, or None if it is empty.

§Examples
let x = &mut [0, 1, 2];

if let Some(first) = x.first_mut() {
    *first = 5;
}
assert_eq!(x, &[5, 1, 2]);

let y: &mut [i32] = &mut [];
assert_eq!(None, y.first_mut());
1.5.0 · Source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

§Examples
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first() {
    assert_eq!(first, &0);
    assert_eq!(elements, &[1, 2]);
}
1.5.0 · Source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

§Examples
let x = &mut [0, 1, 2];

if let Some((first, elements)) = x.split_first_mut() {
    *first = 3;
    elements[0] = 4;
    elements[1] = 5;
}
assert_eq!(x, &[3, 4, 5]);
1.5.0 · Source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

§Examples
let x = &[0, 1, 2];

if let Some((last, elements)) = x.split_last() {
    assert_eq!(last, &2);
    assert_eq!(elements, &[0, 1]);
}
1.5.0 · Source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

§Examples
let x = &mut [0, 1, 2];

if let Some((last, elements)) = x.split_last_mut() {
    *last = 3;
    elements[0] = 4;
    elements[1] = 5;
}
assert_eq!(x, &[4, 5, 3]);
1.0.0 · Source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

§Examples
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());

let w: &[i32] = &[];
assert_eq!(None, w.last());
1.0.0 · Source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

§Examples
let x = &mut [0, 1, 2];

if let Some(last) = x.last_mut() {
    *last = 10;
}
assert_eq!(x, &[0, 1, 10]);

let y: &mut [i32] = &mut [];
assert_eq!(None, y.last_mut());
1.77.0 · Source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Returns an array reference to the first N items in the slice.

If the slice is not at least N in length, this will return None.

§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());

let v: &[i32] = &[10];
assert_eq!(None, v.first_chunk::<2>());

let w: &[i32] = &[];
assert_eq!(Some(&[]), w.first_chunk::<0>());
1.77.0 · Source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Returns a mutable array reference to the first N items in the slice.

If the slice is not at least N in length, this will return None.

§Examples
let x = &mut [0, 1, 2];

if let Some(first) = x.first_chunk_mut::<2>() {
    first[0] = 5;
    first[1] = 4;
}
assert_eq!(x, &[5, 4, 2]);

assert_eq!(None, x.first_chunk_mut::<4>());
1.0.0 · Source

pub fn get<I>(&self, index: I) -> Option<&I::Output>
where I: SliceIndex<Self>,

Returns a reference to an element or subslice depending on the type of index.

  • If given a position, returns a reference to the element at that position or None if out of bounds.
  • If given a range, returns the subslice corresponding to that range, or None if out of bounds.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));
1.0.0 · Source

pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
where I: SliceIndex<Self>,

Returns a mutable reference to an element or subslice depending on the type of index (see get) or None if the index is out of bounds.

§Examples
let x = &mut [0, 1, 2];

if let Some(elem) = x.get_mut(1) {
    *elem = 42;
}
assert_eq!(x, &[0, 42, 2]);
1.0.0 · Source

pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
where I: SliceIndex<Self>,

Returns a reference to an element or subslice, without doing bounds checking.

For a safe alternative see get.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

You can think of this like .get(index).unwrap_unchecked(). It’s UB to call .get_unchecked(len), even if you immediately convert to a pointer. And it’s UB to call .get_unchecked(..len + 1), .get_unchecked(..=len), or similar.

§Examples
let x = &[1, 2, 4];

unsafe {
    assert_eq!(x.get_unchecked(1), &2);
}
1.0.0 · Source

pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
where I: SliceIndex<Self>,

Returns a mutable reference to an element or subslice, without doing bounds checking.

For a safe alternative see get_mut.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

You can think of this like .get_mut(index).unwrap_unchecked(). It’s UB to call .get_unchecked_mut(len), even if you immediately convert to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), .get_unchecked_mut(..=len), or similar.

§Examples
let x = &mut [1, 2, 4];

unsafe {
    let elem = x.get_unchecked_mut(1);
    *elem = 13;
}
assert_eq!(x, &[1, 13, 4]);
1.0.0 · Source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

The caller must ensure that the slice outlives the pointer this function returns, or else it will end up dangling.

The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell) using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

Modifying the container referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.

§Examples
let x = &[1, 2, 4];
let x_ptr = x.as_ptr();

unsafe {
    for i in 0..x.len() {
        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
    }
}
1.0.0 · Source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

The caller must ensure that the slice outlives the pointer this function returns, or else it will end up dangling.

Modifying the container referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.

§Examples
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr();

unsafe {
    for i in 0..x.len() {
        *x_ptr.add(i) += 2;
    }
}
assert_eq!(x, &[3, 4, 6]);
1.93.0 · Source

pub fn as_array<const N: usize>(&self) -> Option<&[T; N]>

Gets a reference to the underlying array.

If N is not exactly equal to the length of self, then this method returns None.

1.93.0 · Source

pub fn as_mut_array<const N: usize>(&mut self) -> Option<&mut [T; N]>

Gets a mutable reference to the slice’s underlying array.

If N is not exactly equal to the length of self, then this method returns None.

1.0.0 · Source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

If a equals to b, it’s guaranteed that elements won’t change value.

§Arguments
  • a - The index of the first element
  • b - The index of the second element
§Panics

Panics if a or b are out of bounds.

§Examples
let mut v = ["a", "b", "c", "d", "e"];
v.swap(2, 4);
assert!(v == ["a", "b", "e", "d", "c"]);
1.0.0 · Source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

The iterator yields all items from start to end.

§Examples
let x = &[1, 2, 4];
let mut iterator = x.iter();

assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);
1.0.0 · Source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

The iterator yields all items from start to end.

§Examples
let x = &mut [1, 2, 4];
for elem in x.iter_mut() {
    *elem += 2;
}
assert_eq!(x, &[3, 4, 6]);
1.0.0 · Source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length size. The windows overlap. If the slice is shorter than size, the iterator returns no values.

§Panics

Panics if size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.windows(3);
assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
assert!(iter.next().is_none());

If the slice is shorter than size:

let slice = ['f', 'o', 'o'];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());

Because the Iterator trait cannot represent the required lifetimes, there is no windows_mut analog to windows; [0,1,2].windows_mut(2).collect() would violate the rules of references (though a LendingIterator analog is possible). You can sometimes use Cell::as_slice_of_cells in conjunction with windows instead:

use std::cell::Cell;

let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
let slice = &mut array[..];
let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
for w in slice_of_cells.windows(3) {
    Cell::swap(&w[0], &w[2]);
}
assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
1.0.0 · Source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact for a variant of this iterator that returns chunks of always exactly chunk_size elements, and rchunks for the same iterator but starting at the end of the slice.

If your chunk_size is a constant, consider using as_chunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert_eq!(iter.next().unwrap(), &['m']);
assert!(iter.next().is_none());
1.0.0 · Source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact_mut for a variant of this iterator that returns chunks of always exactly chunk_size elements, and rchunks_mut for the same iterator but starting at the end of the slice.

If your chunk_size is a constant, consider using as_chunks_mut instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;

for chunk in v.chunks_mut(2) {
    for elem in chunk.iter_mut() {
        *elem += count;
    }
    count += 1;
}
assert_eq!(v, &[1, 1, 2, 2, 3]);
1.31.0 · Source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks.

See chunks for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

If your chunk_size is a constant, consider using as_chunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks_exact(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
1.31.0 · Source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the into_remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks_mut.

See chunks_mut for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of the slice.

If your chunk_size is a constant, consider using as_chunks_mut instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;

for chunk in v.chunks_exact_mut(2) {
    for elem in chunk.iter_mut() {
        *elem += count;
    }
    count += 1;
}
assert_eq!(v, &[1, 1, 2, 2, 0]);
1.88.0 · Source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

Splits the slice into a slice of N-element arrays, assuming that there’s no remainder.

This is the inverse operation to as_flattened.

As this is unsafe, consider whether you could use as_chunks or as_rchunks instead, perhaps via something like if let (chunks, []) = slice.as_chunks() or let (chunks, []) = slice.as_chunks() else { unreachable!() };.

§Safety

This may only be called when

  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • N != 0.
§Examples
let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
    // SAFETY: 1-element chunks never have remainder
    unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
    // SAFETY: The slice length (6) is a multiple of 3
    unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);

// These would be unsound:
// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
1.88.0 · Source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

Splits the slice into a slice of N-element arrays, starting at the beginning of the slice, and a remainder slice with length strictly less than N.

The remainder is meaningful in the division sense. Given let (chunks, remainder) = slice.as_chunks(), then:

  • chunks.len() equals slice.len() / N,
  • remainder.len() equals slice.len() % N, and
  • slice.len() equals chunks.len() * N + remainder.len().

You can flatten the chunks back into a slice-of-T with as_flattened.

§Panics

Panics if N is zero.

Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let (chunks, remainder) = slice.as_chunks();
assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
assert_eq!(remainder, &['m']);

If you expect the slice to be an exact multiple, you can combine let-else with an empty slice pattern:

let slice = ['R', 'u', 's', 't'];
let (chunks, []) = slice.as_chunks::<2>() else {
    panic!("slice didn't have even length")
};
assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
1.0.0 · Source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

§Panics

Panics if mid > len. For a non-panicking alternative see split_at_checked.

§Examples
let v = ['a', 'b', 'c'];

{
   let (left, right) = v.split_at(0);
   assert_eq!(left, []);
   assert_eq!(right, ['a', 'b', 'c']);
}

{
    let (left, right) = v.split_at(2);
    assert_eq!(left, ['a', 'b']);
    assert_eq!(right, ['c']);
}

{
    let (left, right) = v.split_at(3);
    assert_eq!(left, ['a', 'b', 'c']);
    assert_eq!(right, []);
}
1.0.0 · Source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

§Panics

Panics if mid > len. For a non-panicking alternative see split_at_mut_checked.

§Examples
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.split_at_mut(2);
assert_eq!(left, [1, 0]);
assert_eq!(right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1.79.0 · Source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= self.len().

§Examples
let v = ['a', 'b', 'c'];

unsafe {
   let (left, right) = v.split_at_unchecked(0);
   assert_eq!(left, []);
   assert_eq!(right, ['a', 'b', 'c']);
}

unsafe {
    let (left, right) = v.split_at_unchecked(2);
    assert_eq!(left, ['a', 'b']);
    assert_eq!(right, ['c']);
}

unsafe {
    let (left, right) = v.split_at_unchecked(3);
    assert_eq!(left, ['a', 'b', 'c']);
    assert_eq!(right, []);
}
1.79.0 · Source

pub unsafe fn split_at_mut_unchecked( &mut self, mid: usize, ) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at_mut.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= self.len().

§Examples
let mut v = [1, 0, 3, 0, 5, 6];
// scoped to restrict the lifetime of the borrows
unsafe {
    let (left, right) = v.split_at_mut_unchecked(2);
    assert_eq!(left, [1, 0]);
    assert_eq!(right, [3, 0, 5, 6]);
    left[1] = 2;
    right[1] = 4;
}
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1.80.0 · Source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is too short.

If mid ≤ len returns a pair of slices where the first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Otherwise, if mid > len, returns None.

§Examples
let v = [1, -2, 3, -4, 5, -6];

{
   let (left, right) = v.split_at_checked(0).unwrap();
   assert_eq!(left, []);
   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
}

{
    let (left, right) = v.split_at_checked(2).unwrap();
    assert_eq!(left, [1, -2]);
    assert_eq!(right, [3, -4, 5, -6]);
}

{
    let (left, right) = v.split_at_checked(6).unwrap();
    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
    assert_eq!(right, []);
}

assert_eq!(None, v.split_at_checked(7));
1.80.0 · Source

pub fn split_at_mut_checked( &mut self, mid: usize, ) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the slice is too short.

If mid ≤ len returns a pair of slices where the first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Otherwise, if mid > len, returns None.

§Examples
let mut v = [1, 0, 3, 0, 5, 6];

if let Some((left, right)) = v.split_at_mut_checked(2) {
    assert_eq!(left, [1, 0]);
    assert_eq!(right, [3, 0, 5, 6]);
    left[1] = 2;
    right[1] = 4;
}
assert_eq!(v, [1, 2, 3, 4, 5, 6]);

assert_eq!(None, v.split_at_mut_checked(7));
1.0.0 · Source

pub fn starts_with(&self, needle: &[T]) -> bool
where T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

§Examples
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(v.starts_with(&v));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));

Always returns true if needle is an empty slice:

let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));
1.0.0 · Source

pub fn ends_with(&self, needle: &[T]) -> bool
where T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

§Examples
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(v.ends_with(&v));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));

Always returns true if needle is an empty slice:

let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));
1.0.0 · Source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

The comparator function should return an order code that indicates whether its argument is Less, Equal or Greater the desired target. If the slice is not sorted or if the comparator function does not implement an order consistent with the sort order of the underlying slice, the returned result is unspecified and meaningless.

If the value is found then Result::Ok is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then Result::Err is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search, binary_search_by_key, and partition_point.

§Examples

Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let seek = 13;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
let seek = 4;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
let seek = 100;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
let seek = 1;
let r = s.binary_search_by(|probe| probe.cmp(&seek));
assert!(match r { Ok(1..=4) => true, _ => false, });
1.10.0 · Source

pub fn binary_search_by_key<'a, B, F>( &'a self, b: &B, f: F, ) -> Result<usize, usize>
where F: FnMut(&'a T) -> B, B: Ord,

Binary searches this slice with a key extraction function.

Assumes that the slice is sorted by the key, for instance with sort_by_key using the same key extraction function. If the slice is not sorted by the key, the returned result is unspecified and meaningless.

If the value is found then Result::Ok is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then Result::Err is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search, binary_search_by, and partition_point.

§Examples

Looks up a series of four elements in a slice of pairs sorted by their second elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
         (1, 21), (2, 34), (4, 55)];

assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
let r = s.binary_search_by_key(&1, |&(a, b)| b);
assert!(match r { Ok(1..=4) => true, _ => false, });
1.26.0 · Source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the slice move to the end while the last self.len() - mid elements move to the front.

After calling rotate_left, the element previously at index mid will become the first element in the slice.

§Panics

This function will panic if mid is greater than the length of the slice. Note that mid == self.len() does not panic and is a no-op rotation.

§Complexity

Takes linear (in self.len()) time.

§Examples
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.rotate_left(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);

Rotating a subslice:

let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a[1..5].rotate_left(1);
assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
1.26.0 · Source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k elements of the slice move to the end while the last k elements move to the front.

After calling rotate_right, the element previously at index self.len() - k will become the first element in the slice.

§Panics

This function will panic if k is greater than the length of the slice. Note that k == self.len() does not panic and is a no-op rotation.

§Complexity

Takes linear (in self.len()) time.

§Examples
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.rotate_right(2);
assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);

Rotating a subslice:

let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a[1..5].rotate_right(1);
assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
1.50.0 · Source

pub fn fill(&mut self, value: T)
where T: Clone,

Fills self with elements by cloning value.

§Examples
let mut buf = vec![0; 10];
buf.fill(1);
assert_eq!(buf, vec![1; 10]);
1.7.0 · Source

pub fn clone_from_slice(&mut self, src: &[T])
where T: Clone,

Copies the elements from src into self.

The length of src must be the same as self.

§Panics

This function will panic if the two slices have different lengths.

§Examples

Cloning two elements from a slice into another:

let src = [1, 2, 3, 4];
let mut dst = [0, 0];

// Because the slices have to be the same length,
// we slice the source slice from four elements
// to two. It will panic if we don't do this.
dst.clone_from_slice(&src[2..]);

assert_eq!(src, [1, 2, 3, 4]);
assert_eq!(dst, [3, 4]);

Rust enforces that there can only be one mutable reference with no immutable references to a particular piece of data in a particular scope. Because of this, attempting to use clone_from_slice on a single slice will result in a compile failure:

let mut slice = [1, 2, 3, 4, 5];

slice[..2].clone_from_slice(&slice[3..]); // compile fail!

To work around this, we can use split_at_mut to create two distinct sub-slices from a slice:

let mut slice = [1, 2, 3, 4, 5];

{
    let (left, right) = slice.split_at_mut(2);
    left.clone_from_slice(&right[1..]);
}

assert_eq!(slice, [4, 5, 3, 4, 5]);
1.9.0 · Source

pub fn copy_from_slice(&mut self, src: &[T])
where T: Copy,

Copies all elements from src into self, using a memcpy.

The length of src must be the same as self.

If T does not implement Copy, use clone_from_slice.

§Panics

This function will panic if the two slices have different lengths.

§Examples

Copying two elements from a slice into another:

let src = [1, 2, 3, 4];
let mut dst = [0, 0];

// Because the slices have to be the same length,
// we slice the source slice from four elements
// to two. It will panic if we don't do this.
dst.copy_from_slice(&src[2..]);

assert_eq!(src, [1, 2, 3, 4]);
assert_eq!(dst, [3, 4]);

Rust enforces that there can only be one mutable reference with no immutable references to a particular piece of data in a particular scope. Because of this, attempting to use copy_from_slice on a single slice will result in a compile failure:

let mut slice = [1, 2, 3, 4, 5];

slice[..2].copy_from_slice(&slice[3..]); // compile fail!

To work around this, we can use split_at_mut to create two distinct sub-slices from a slice:

let mut slice = [1, 2, 3, 4, 5];

{
    let (left, right) = slice.split_at_mut(2);
    left.copy_from_slice(&right[1..]);
}

assert_eq!(slice, [4, 5, 3, 4, 5]);
1.30.0 · Source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmutes the slice to a slice of another type, ensuring alignment of the types is maintained.

This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new type, and the suffix slice. The middle part will be as big as possible under the given alignment constraint and element size.

This method has no purpose when either input element T or output element U are zero-sized and will return the original slice without splitting anything.

§Safety

This method is essentially a transmute with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

§Examples

Basic usage:

unsafe {
    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
    // less_efficient_algorithm_for_bytes(prefix);
    // more_efficient_algorithm_for_aligned_shorts(shorts);
    // less_efficient_algorithm_for_bytes(suffix);
}
1.30.0 · Source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmutes the mutable slice to a mutable slice of another type, ensuring alignment of the types is maintained.

This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new type, and the suffix slice. The middle part will be as big as possible under the given alignment constraint and element size.

This method has no purpose when either input element T or output element U are zero-sized and will return the original slice without splitting anything.

§Safety

This method is essentially a transmute with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

§Examples

Basic usage:

unsafe {
    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
    // less_efficient_algorithm_for_bytes(prefix);
    // more_efficient_algorithm_for_aligned_shorts(shorts);
    // less_efficient_algorithm_for_bytes(suffix);
}
1.79.0 · Source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this slice, and the non-UTF-8 fragments in between.

See the [Utf8Chunk] type for documentation of the items yielded by this iterator.

§Examples

This function formats arbitrary but mostly-UTF-8 bytes into Rust source code in the form of a C-string literal (c"...").

use std::fmt::Write as _;

pub fn cstr_literal(bytes: &[u8]) -> String {
    let mut repr = String::new();
    repr.push_str("c\"");
    for chunk in bytes.utf8_chunks() {
        for ch in chunk.valid().chars() {
            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
            write!(repr, "{}", ch.escape_debug()).unwrap();
        }
        for byte in chunk.invalid() {
            write!(repr, "\\x{:02X}", byte).unwrap();
        }
    }
    repr.push('"');
    repr
}

fn main() {
    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
    let expected = stringify!(c"\xFErris the 🦀\u{7}");
    assert_eq!(lit, expected);
}

Trait Implementations§

Source§

impl Debug for ByteStr

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for ByteStr

Source§

type Target = [u8]

The resulting type after dereferencing.
Source§

fn deref(&self) -> &[u8]

Dereferences the value.
Source§

impl DerefMut for ByteStr

Source§

fn deref_mut(&mut self) -> &mut [u8]

Mutably dereferences the value.
Source§

impl DerefPure for ByteStr

Auto Trait Implementations§

§

impl Freeze for ByteStr

§

impl Send for ByteStr

§

impl !Sized for ByteStr

§

impl Sync for ByteStr

§

impl Unpin for ByteStr

Blanket Implementations§

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types #44874)
The target type on which the method may be called.