Hi!
I have a hard time understanding how to write code with traits.
In the following example, I created a Trait Sample, that for each numeric type implements a function to_bytes.
My goal here is to read a file from hound
create, and for each hound::Sample
send it through the channel and then "process" it using the function to_bytes
.
So in each step "don't care about the type of the value", only that implements the Sample Trait.
Rust instead is showing me that it cares about it.
use std::sync::Arc;
pub trait Sample
{
fn to_bytes(&self) -> Arc<[u8]>;
}
// implement the macro for all the numeric types
macro_rules! implement_sample {
($($t:ty),*) => {
$(
impl Sample for $t {
fn to_bytes(&self) -> Arc<[u8]> {
self.to_le_bytes().into()
}
}
)*
};
}
implement_sample!(u8, i8, u16, i16, u32, i32, f32, u64, i64, f64, u128, i128, usize, isize);
async fn test_something<S: Sample>(mut rx: tokio::sync::mpsc::Receiver<S>)
{
let mut count = 0;
while let Some(sample) = rx.recv().await {
let s = sample.to_bytes();
println!("{:?}", s);
count += 1;
}
println!("Received {} samples", count);
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn using_hound_sample() {
let (tx, rx) = tokio::sync::mpsc::channel(1);
tokio::task::spawn_blocking(move || {
let mut file = hound::WavReader::open("tests/sample.wav")
.expect("Error opening file");
file.samples()
.map(|s| s.unwrap())
.for_each(|s| tx.blocking_send(s).unwrap())
});
test_something(rx).await;
}
}
How can I instruct Rust to send the s: hound::Sample
file.samples()
.map(|s| s.unwrap())
.for_each(|s| tx.blocking_send(s).unwrap())
});
through the tx Sender
given that s
will be a type (i16, i32, or f32) that implements my Sample
trait?
What am I missing here?
Thanks a lot!
P.S. A link to the documentation explaining this kind of situation would be highly appreciated!