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)