I know that Rust does not support variable length arrays, but this leaves me wondering what to replace them, given that:
- I don't want to allocate and free tiny Vec in a loop
- The borrow controller does not allow me to move the code outside the loop
- There are many limitations to fixed-size arrays, so I cannot figure out how to use them.
The C code that I convert processes the image, calling a callback on each line, passing a small array of pointers:
float *tmp[img->channels]; // Small, up to 4 elements for(int y = 0; y < height; y++) { for(int ch = 0; ch < img->channels; ch++) { tmp[ch] = &img->channel[ch]->pixels[width * y]; } callback(tmp, img->channels); }
My rust attempt ( example in playpen ):
for y in 0..height { let tmp = &img.channel.iter().map(|channel| { &mut channel.pixels.as_ref().unwrap()[width * y .. width * (y+1)] }).collect(); callback(tmp); }
But he rejected:
a collection of type [&mut [f32]] cannot be constructed from an iterator over elements of type &mut [f32]
Unfortunately, this sounds exactly like I tried!
I tried using a fixed-size array, but Rust does not support generics on them, so I cannot populate it from an iterator, and I cannot populate them in a C-like loop, because the links made in the loop don't expect it.
flag core::iter::FromIterator<&mut [f32]> not implemented for type [&mut [f32]; 4] [&mut [f32]; 4]
Another approach using a memory fragment from a fixed-size array also fails:
let mut row_tmp: [&mut [f32]; 4] = unsafe{mem::zeroed()}; for y in 0..height { row_tmp[0..channels].iter_mut().zip(img.chan.iter_mut()).map(|(t, chan)| { *t = &mut chan.img.as_ref().unwrap()[(width * y) as usize .. (width * (y+1)) as usize] }); cb(&row_tmp[0..channels], y, width, image_data); }
error: cannot take img.chan as mutable more than once at a time