I am trying to extract the bytes of a usize
to retrieve them in a u8
array but it seems impossible to initialize an array with a "runtime-known" size.
Here is my code:
use std::mem;
use std::mem::transmute;
fn encodeString(value: &str) {
let length: usize = value.len(); // retrieval of the size
let lengthSize: usize = mem::size_of_val(&length); // I am on 64-bit so it is 8
let lengthBytes: [u8; lengthSize] = unsafe { transmute(lengthSize.to_be() }; // BAM. Does not want to compile because of the lengthSize
}
fn main() {
encodeString("Coucou");
}
I tried to set the lengthSize
variable as a constant using const
instead of let
but, as you will notice, I have the error that it is not "constant".
Because I did not succeed in doing what I wanted, I tried another way by using a Vec
but... I have another error concerning its size and I did not find how I can force to use a Vec
with only 8 entries of u8
:
let lengthBytes: Vec<u8> = unsafe { transmute(length.to_be()) }; // BAM. 15:50 error: transmute called with differently sized types: usize (64 bits) to std::vec::Vec<u8> (192 bits) [E0512]
Maybe if I convert the usize
to a string and then I convert it back to a u8
array? But that seems to be... overkill.
==== My solution
So... I found another way by rotating the bits. Here is my code:
fn splitToVector(value: usize) -> Vec<u8> {
println!("Value of the usize: {}", value);
let length = mem::size_of_val(&value);
println!("Usize coded on {} bytes", length);
let mut splitted_value: Vec<u8> = Vec::with_capacity(length);
for x in 1..length + 1 {
let bitPack: u8 = value.rotate_left(8 * x as u32) as u8;
println!("Content of the bitPack number {}: {}", x, bitPack);
splitted_value.push(bitPack);
}
return splitted_value;
}
fn main {
let coucou_size: usize = "Coucou".len();
let coucou_size_bytes = splitToVector(coucou_size);
assert_eq!(coucou_size_bytes.capacity(), mem::size_of_val(&coucou_size));
assert_eq!(String::from_utf8(coucou_size_bytes).unwrap().as_bytes(), coucou_size.to_string().as_bytes());
}
The function that splits the usize in bytes is splitToVector which returns a vector of u8 because it is impossible to define the length of an array at runtime (as defined in this post provided by Shepmaster: How to set a Rust array length dynamically)