I created a Task struct that holds two files and an enum. For this struct, I want to implement a method that reads and decodes the input file as a WAV (audio). For that, I'm using the wav crate. This method should return a Header holding some metadata on the file and a Vec<f32>, which is the audio data itself.
The problem is that I only have ways to get a reference to this audio vector (as_thirty_two_float()). This reference is owned by the read object created in the first line. I am not allowed to return the reference because read will be disposed soon after. I am also not allowed to return the content (*data_vector) because "cannot move out of *data_vector which is behind a shared reference: move occurs because *data_vector has type Vec<f32>, which does not implement the Copy trait".
Obviously I could just clone the vector and be done with it, but I want to believe that there is a way to just take the ownership of *data_vector by destroying read in the process. Could anyone throw some light on this for me?
struct Task {
input_file: File,
output_file: File,
effect: Effect,
}
impl Task {
fn decode_input(&mut self) -> (Header, Vec<f32>) {
let read = wav::read(&mut self.input_file)
.expect("Failed to decode the input file");
let data_vector = read.1.as_thirty_two_float() // &Vec<f32>
.expect("Failed to extract the audio channel data");
return (read.0, *data_vector);
}
}
You could use try_into_thirty_two_float() which moves the vector out of the BitDepth on success or returns the BitDepth unchanged on failure.
let (header, bitdepth) = wav::read(&mut self.input_file)
.expect("Failed to decode the input file");
let data_vector = bitdepth.try_into_thirty_two_float()
.expect("Failed to extract the audio channel data");
(header, data_vector)