1#![allow(unsafe_code)]
2
3use crate::sealed::Sealed;
4
5use alloc::string::String;
6use alloc::vec::Vec;
7
8#[derive(Debug, thiserror::Error)]
9#[error("invalid utf8 string")]
10pub struct Utf8Error {
11 bytes: Vec<u8>,
12}
13
14impl Utf8Error {
15 #[must_use]
16 pub fn into_bytes(self) -> Vec<u8> {
17 self.bytes
18 }
19}
20
21pub trait StringExt: Sealed {
22 fn from_utf8_simd(bytes: Vec<u8>) -> Result<String, Utf8Error>;
23}
24
25impl Sealed for String {}
26
27impl StringExt for String {
28 fn from_utf8_simd(bytes: Vec<u8>) -> Result<String, Utf8Error> {
29 match simdutf8::basic::from_utf8(&bytes) {
30 Ok(_) => Ok(unsafe { String::from_utf8_unchecked(bytes) }),
31 Err(_) => Err(Utf8Error { bytes }),
32 }
33 }
34}