NOTE: There are multiple solutions to this problem. I'd recommend reading the entire discussion.
I have a byte array slice like [12, 63, 0, 0, 4, 0, 62]
and need to pull out the values at indicies 2, 3, 4, and 5 and then convert that sub-slice into an i32
.
Some things to note:
- I do not know the size of the bigger byte array and comp time
- I do not know the starting index of the 4 bytes of interest at comp time
- I DO know that it will always be exactly 4 bytes that I need to convert into an i32
- The larger byte stream is actually a
heapless::Vec
if that matters. - This is in a no_std environment.
I have tried two things and gotten size errors each time.
Simple Slice
let byte_stream = heapless::Vec<u8, 20>::from_slice(&[12, 63, 0, 0, 4, 0, 62]);
let starting_index = 2; // discovered at runtime
let ending_index = 6; // discovered at runtime, exclusive
let value_bytes: &[u8; 4] = &byte_stream[starting_index..ending_index];
let value = i32::from_be_bytes(*value_bytes);
This fails with:
error[E0308]: mismatched types
--> src/main.rs:20:33
|
20 | let value_bytes: &[u8; 4] = &byte_stream[starting_index..ending_index];
| -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected array `[u8; 4]`, found slice `[u8]`
| |
| expected due to this
|
= note: expected reference `&[u8; 4]`
found reference `&[u8]`
which makes sense. But, when I try let value_bytes: &[u8; 4]
, then I get the same mismatched types error, just at i32::from_be_bytes(*value_bytes);
Building an array
let byte_stream: Vec<u8, 20> = Vec::from_slice(&[12, 63, 0, 0, 4, 0, 62]).unwrap();
let starting_index = 2; // discovered at runtime
let ending_index = 6; // discovered at runtime, exclusive
let mut value_bytes: &[u8; 4] = &[0; 4];
let mut i: usize = 0;
for byte in &byte_stream[starting_index..ending_index] {
value_bytes[i] = *byte;
i += 1;
}
let value = Some(i32::from_be_bytes(*value_bytes));
println!("{:?}", value);
This errors with
error[E0594]: cannot assign to `value_bytes[_]` which is behind a `&` reference
--> src/main.rs:27:9
|
23 | let mut value_bytes: &[u8; 4] = &[0; 4];
| ------- help: consider changing this to be a mutable reference: `&mut [0; 4]`
...
27 | value_bytes[i] = *byte;
| ^^^^^^^^^^^^^^^^^^^^^^ `value_bytes` is a `&` reference, so the data it refers to cannot be written
But value_bytes
IS mutable?
What am I missing? Thanks!