core/str/converts.rs
1//! Ways to create a `str` from bytes slice.
2
3use super::Utf8Error;
4use super::validations::run_utf8_validation;
5#[cfg(not(feature = "ferrocene_certified"))]
6use crate::{mem, ptr};
7
8// Ferrocene addition: Imports for certified subset
9#[cfg(feature = "ferrocene_certified")]
10#[rustfmt::skip]
11use crate::mem;
12
13/// Converts a slice of bytes to a string slice.
14///
15/// This is an alias to [`str::from_utf8`].
16///
17/// A string slice ([`&str`]) is made of bytes ([`u8`]), and a byte slice
18/// ([`&[u8]`][byteslice]) is made of bytes, so this function converts between
19/// the two. Not all byte slices are valid string slices, however: [`&str`] requires
20/// that it is valid UTF-8. `from_utf8()` checks to ensure that the bytes are valid
21/// UTF-8, and then does the conversion.
22///
23/// [`&str`]: str
24/// [byteslice]: slice
25///
26/// If you are sure that the byte slice is valid UTF-8, and you don't want to
27/// incur the overhead of the validity check, there is an unsafe version of
28/// this function, [`from_utf8_unchecked`], which has the same
29/// behavior but skips the check.
30///
31/// If you need a `String` instead of a `&str`, consider
32/// [`String::from_utf8`][string].
33///
34/// [string]: ../../std/string/struct.String.html#method.from_utf8
35///
36/// Because you can stack-allocate a `[u8; N]`, and you can take a
37/// [`&[u8]`][byteslice] of it, this function is one way to have a
38/// stack-allocated string. There is an example of this in the
39/// examples section below.
40///
41/// [byteslice]: slice
42///
43/// # Errors
44///
45/// Returns `Err` if the slice is not UTF-8 with a description as to why the
46/// provided slice is not UTF-8.
47///
48/// # Examples
49///
50/// Basic usage:
51///
52/// ```
53/// use std::str;
54///
55/// // some bytes, in a vector
56/// let sparkle_heart = vec![240, 159, 146, 150];
57///
58/// // We can use the ? (try) operator to check if the bytes are valid
59/// let sparkle_heart = str::from_utf8(&sparkle_heart)?;
60///
61/// assert_eq!("💖", sparkle_heart);
62/// # Ok::<_, str::Utf8Error>(())
63/// ```
64///
65/// Incorrect bytes:
66///
67/// ```
68/// use std::str;
69///
70/// // some invalid bytes, in a vector
71/// let sparkle_heart = vec![0, 159, 146, 150];
72///
73/// assert!(str::from_utf8(&sparkle_heart).is_err());
74/// ```
75///
76/// See the docs for [`Utf8Error`] for more details on the kinds of
77/// errors that can be returned.
78///
79/// A "stack allocated string":
80///
81/// ```
82/// use std::str;
83///
84/// // some bytes, in a stack-allocated array
85/// let sparkle_heart = [240, 159, 146, 150];
86///
87/// // We know these bytes are valid, so just use `unwrap()`.
88/// let sparkle_heart: &str = str::from_utf8(&sparkle_heart).unwrap();
89///
90/// assert_eq!("💖", sparkle_heart);
91/// ```
92#[stable(feature = "rust1", since = "1.0.0")]
93#[rustc_const_stable(feature = "const_str_from_utf8_shared", since = "1.63.0")]
94#[rustc_diagnostic_item = "str_from_utf8"]
95pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
96    // FIXME(const-hack): This should use `?` again, once it's `const`
97    match run_utf8_validation(v) {
98        Ok(_) => {
99            // SAFETY: validation succeeded.
100            Ok(unsafe { from_utf8_unchecked(v) })
101        }
102        Err(err) => Err(err),
103    }
104}
105
106/// Converts a mutable slice of bytes to a mutable string slice.
107///
108/// This is an alias to [`str::from_utf8_mut`].
109///
110/// # Examples
111///
112/// Basic usage:
113///
114/// ```
115/// use std::str;
116///
117/// // "Hello, Rust!" as a mutable vector
118/// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33];
119///
120/// // As we know these bytes are valid, we can use `unwrap()`
121/// let outstr = str::from_utf8_mut(&mut hellorust).unwrap();
122///
123/// assert_eq!("Hello, Rust!", outstr);
124/// ```
125///
126/// Incorrect bytes:
127///
128/// ```
129/// use std::str;
130///
131/// // Some invalid bytes in a mutable vector
132/// let mut invalid = vec![128, 223];
133///
134/// assert!(str::from_utf8_mut(&mut invalid).is_err());
135/// ```
136/// See the docs for [`Utf8Error`] for more details on the kinds of
137/// errors that can be returned.
138#[stable(feature = "str_mut_extras", since = "1.20.0")]
139#[rustc_const_stable(feature = "const_str_from_utf8", since = "1.87.0")]
140#[rustc_diagnostic_item = "str_from_utf8_mut"]
141#[cfg(not(feature = "ferrocene_certified"))]
142pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
143    // FIXME(const-hack): This should use `?` again, once it's `const`
144    match run_utf8_validation(v) {
145        Ok(_) => {
146            // SAFETY: validation succeeded.
147            Ok(unsafe { from_utf8_unchecked_mut(v) })
148        }
149        Err(err) => Err(err),
150    }
151}
152
153/// Converts a slice of bytes to a string slice without checking
154/// that the string contains valid UTF-8.
155///
156/// This is an alias to [`str::from_utf8_unchecked`].
157///
158/// See the safe version, [`from_utf8`], for more information.
159///
160/// # Safety
161///
162/// The bytes passed in must be valid UTF-8.
163///
164/// # Examples
165///
166/// Basic usage:
167///
168/// ```
169/// use std::str;
170///
171/// // some bytes, in a vector
172/// let sparkle_heart = vec![240, 159, 146, 150];
173///
174/// let sparkle_heart = unsafe {
175///     str::from_utf8_unchecked(&sparkle_heart)
176/// };
177///
178/// assert_eq!("💖", sparkle_heart);
179/// ```
180#[inline]
181#[must_use]
182#[stable(feature = "rust1", since = "1.0.0")]
183#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
184#[rustc_diagnostic_item = "str_from_utf8_unchecked"]
185pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
186    // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
187    // Also relies on `&str` and `&[u8]` having the same layout.
188    unsafe { mem::transmute(v) }
189}
190
191/// Converts a slice of bytes to a string slice without checking
192/// that the string contains valid UTF-8; mutable version.
193///
194/// This is an alias to [`str::from_utf8_unchecked_mut`].
195///
196/// See the immutable version, [`from_utf8_unchecked()`] for documentation and safety requirements.
197///
198/// # Examples
199///
200/// Basic usage:
201///
202/// ```
203/// use std::str;
204///
205/// let mut heart = vec![240, 159, 146, 150];
206/// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) };
207///
208/// assert_eq!("💖", heart);
209/// ```
210#[inline]
211#[must_use]
212#[stable(feature = "str_mut_extras", since = "1.20.0")]
213#[rustc_const_stable(feature = "const_str_from_utf8_unchecked_mut", since = "1.83.0")]
214#[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"]
215#[cfg(not(feature = "ferrocene_certified"))]
216pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
217    // SAFETY: the caller must guarantee that the bytes `v`
218    // are valid UTF-8, thus the cast to `*mut str` is safe.
219    // Also, the pointer dereference is safe because that pointer
220    // comes from a reference which is guaranteed to be valid for writes.
221    unsafe { &mut *(v as *mut [u8] as *mut str) }
222}
223
224/// Creates a `&str` from a pointer and a length.
225///
226/// The pointed-to bytes must be valid UTF-8.
227/// If this might not be the case, use `str::from_utf8(slice::from_raw_parts(ptr, len))`,
228/// which will return an `Err` if the data isn't valid UTF-8.
229///
230/// This function is the `str` equivalent of [`slice::from_raw_parts`](crate::slice::from_raw_parts).
231/// See that function's documentation for safety concerns and examples.
232///
233/// The mutable version of this function is [`from_raw_parts_mut`].
234#[inline]
235#[must_use]
236#[unstable(feature = "str_from_raw_parts", issue = "119206")]
237#[cfg(not(feature = "ferrocene_certified"))]
238pub const unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str {
239    // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
240    unsafe { &*ptr::from_raw_parts(ptr, len) }
241}
242
243/// Creates a `&mut str` from a pointer and a length.
244///
245/// The pointed-to bytes must be valid UTF-8.
246/// If this might not be the case, use `str::from_utf8_mut(slice::from_raw_parts_mut(ptr, len))`,
247/// which will return an `Err` if the data isn't valid UTF-8.
248///
249/// This function is the `str` equivalent of [`slice::from_raw_parts_mut`](crate::slice::from_raw_parts_mut).
250/// See that function's documentation for safety concerns and examples.
251///
252/// The immutable version of this function is [`from_raw_parts`].
253#[inline]
254#[must_use]
255#[unstable(feature = "str_from_raw_parts", issue = "119206")]
256#[cfg(not(feature = "ferrocene_certified"))]
257pub const unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut str {
258    // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
259    unsafe { &mut *ptr::from_raw_parts_mut(ptr, len) }
260}