#how do I go from `Box<[u8]>` to `Box<str>`?

18 messages · Page 1 of 1 (latest)

keen pine
#

pretty much title, I can't find an api to do this

noble zodiac
#

.into_vec() -> String::from_utf8 -> into_boxed_str()
Shouldn't reallocate

keen pine
#

I guess

#

it's not very pretty :p

#

but it does work

noble zodiac
#

?eval ```rs
let x: Box<[u8]> = Box::new(*b"hello, world!");
let y: Vec<u8> = x.into_vec();
let z: String = String::from_utf8(y).unwrap();
let w: Box<str> = z.into_boxed_str();
w

teal willowBOT
#
"hello, world!"```
noble zodiac
#

Yeah,ideally there'd be a TryFrom<Box<[u8]>> for Box<str>

lone rampart
#

Don't do this (see T-Dark, World's comment below).

?play ```rust
fn from_boxed_utf8(bytes: Box<[u8]>) -> Result<Box<str>, (Box<[u8]>, core::str::Utf8Error)> {
match core::str::from_utf8(&bytes) {
Ok(_) => Ok(unsafe { core::mem::transmute::<Box<[u8]>, Box<str>>(bytes) }),
Err(err) => Err((bytes, err)),
}
}

teal willowBOT
lone rampart
#

You can avoid the allocation of the Vec by checking whether the bytes are valid UTF-8, and, if so, just changing the type.

balmy basin
#

Box doesn't promise to have the same layout across types. You're supposed to into_raw, cast, and from_raw

vernal rover
#
fn from_boxed_utf8(bytes: Box<[u8]>) -> Result<Box<str>, (Box<[u8]>, core::str::Utf8Error)> {
    match core::str::from_utf8(&bytes) {
-        Ok(_) => Ok(unsafe { core::mem::transmute::<Box<[u8]>, Box<str>>(bytes) }),
+        Ok(_) => Ok(unsafe { std::str::from_boxed_utf8_unchecked(bytes) }),
        Err(err) => Err((bytes, err)),
    }
}
noble zodiac
balmy basin
#

The opposite direction, however, can. Though not in this case: It doesn't reallocate if len == capacity

lone rampart