Cast i8 to u8 vec in Rust?

Is there a better way to convert a Vec<i8> to Vec<u8> in Rust than the two methods mentioned?

Rewrite

Is there a more efficient way to convert a Vec<i8> to Vec<u8> in Rust than the two currently known methods?

The first method is slow, as it involves creating a copy of the vector and casting each entry. The second method involves using std::transmute, which is discouraged according to the documentation.

Background: I’m receiving a Vec<i8> from an unsafe gl::GetShaderInfoLog() call and intend to create a String from this vector of characters using String::from_utf8().

To convert a Vec<i8> to Vec<u8> more efficiently in Rust, you can use the Vec::into_raw_parts method. Here’s how:

use std::mem;

fn convert_vec_i8_to_vec_u8(vec_i8: Vec<i8>) -> Vec<u8> {
    let mut vec_u8 = Vec::new();
    
    let vec_i8_len = vec_i8.len();
    vec_u8.reserve_exact(vec_i8_len);
    
    let (ptr, len, cap) = vec_i8.into_raw_parts();
    mem::forget(vec_i8);
    
    unsafe {
        vec_u8.set_len(len);
        std::ptr::copy(ptr as *const u8, vec_u8.as_mut_ptr(), len);
    }
    
    vec_u8
}

This method avoids unnecessary copying and uses the raw representation of the vector to directly convert i8 elements to u8. Be cautious when using into_raw_parts as it can lead to memory leaks if not handled properly.