rune_alloc/
str.rs

1//! Utilities for the `str` primitive type.
2//!
3//! *[See also the `str` primitive type](str).*
4
5use crate::alloc::{Allocator, Global};
6use crate::borrow::TryToOwned;
7use crate::boxed::Box;
8use crate::error::Error;
9use crate::string::String;
10
11/// Converts a boxed slice of bytes to a boxed string slice without checking
12/// that the string contains valid UTF-8.
13///
14/// # Examples
15///
16/// ```
17/// use rune::alloc::Box;
18/// use rune::alloc::str;
19///
20/// let smile_utf8 = Box::try_from([226, 152, 186])?;
21/// let smile = unsafe { str::from_boxed_utf8_unchecked(smile_utf8) };
22///
23/// assert_eq!("☺", &*smile);
24/// # Ok::<_, rune::alloc::Error>(())
25/// ```
26///
27/// # Safety
28///
29/// The provided buffer must be valid UTF-8.
30#[must_use]
31#[inline]
32pub unsafe fn from_boxed_utf8_unchecked<A: Allocator>(v: Box<[u8], A>) -> Box<str, A> {
33    let (ptr, alloc) = Box::into_raw_with_allocator(v);
34    unsafe { Box::from_raw_in(ptr as *mut str, alloc) }
35}
36
37/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
38///
39/// # Examples
40///
41/// Basic usage:
42///
43/// ```
44/// use rune::alloc::String;
45/// use rune::alloc::str;
46/// use rune::alloc::prelude::*;
47///
48/// let string = String::try_from("birthday gift")?;
49/// let boxed_str = string.try_clone()?.try_into_boxed_str()?;
50///
51/// assert_eq!(str::into_string(boxed_str), string);
52/// # Ok::<_, rune::alloc::Error>(())
53/// ```
54#[must_use = "`self` will be dropped if the result is not used"]
55#[inline]
56pub fn into_string<A: Allocator>(this: Box<str, A>) -> String<A> {
57    let slice = Box::<[u8], A>::from(this);
58    let vec = crate::slice::into_vec(slice);
59    unsafe { String::<A>::from_utf8_unchecked(vec) }
60}
61
62impl TryToOwned for str {
63    type Owned = String<Global>;
64
65    #[inline]
66    fn try_to_owned(&self) -> Result<String<Global>, Error> {
67        Ok(unsafe { String::from_utf8_unchecked(self.as_bytes().try_to_owned()?) })
68    }
69}