Use the bytemuck library; specifically bytemuck::cast_slice(). Underneath, it is just the unsafe conversion that has already been described in other answers, but it uses compile-time (type) and run-time (length and alignment) checks to ensure that you don't have to worry about correctly checking the safety conditions.
let data_slice: &[f32] = bytemuck::cast_slice(
&body[buffer_offset..(buffer_offset + buffer_length)
];
Note that this will panic if the beginning and end of the slice are not aligned to 4 bytes. There is no way to avoid this requirement in Rust — if the data is not aligned, you must copy it to a new location that is aligned. (Since your goal is to produce f32s, the simplest way to do that while ensuring the alignment would be to iterate with f32::from_ne_bytes(), performing the f32 conversion and the copy.)