Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bwavfile::raw_chunk_reader is a private module #6

Closed
oscarbailey-xmos opened this issue Dec 2, 2020 · 6 comments
Closed

bwavfile::raw_chunk_reader is a private module #6

oscarbailey-xmos opened this issue Dec 2, 2020 · 6 comments

Comments

@oscarbailey-xmos
Copy link

I'm very new to Rust so I may be doing something wrong - I'm trying to write a function that returns an AudioFrameReader, this is the function:

fn from_wav_filename(wav_filename: &str) -> Result<(WaveFmt, AudioFrameReader<RawChunkReader<std::fs::File>>), ()> {
    if let mut Ok(r) = WaveReader::open(&wav_filename) {
        let format = r.format().unwrap();
        let mut frame_reader = r.audio_frame_reader().unwrap();
        Ok((format, frame_reader))
    } else {
        Err(())
    }
}

However, compilation fails because bwavfile::raw_chunk_reader is a private module:

error[E0603]: module `raw_chunk_reader` is private
   --> src/main.rs:2:15
    |
2   | use bwavfile::raw_chunk_reader::RawChunkReader;
    |               ^^^^^^^^^^^^^^^^ private module
    |

It seems like I'd run into the same issue if I tried adding AudioFrameReader to a custom struct type.

@iluvcapra
Copy link
Owner

It's okay this is my first Rust project too!

I don't think you need to have that use statement in your main. Just remove it and it should compile fine, all you need is bwavefile::WaveReader.

Look at the integration tests and see its pattern of uses, it does this same operation in test_read() that you're doing and you can see how I do it there. Let me know if this helps!

@iluvcapra
Copy link
Owner

iluvcapra commented Dec 2, 2020

Actually looking at this maybe I need to rewrite the AudioFrameReader if you want to be able to spell it out in a return type. I don't want the RawChunkReader to be a part of the interface so it's a bug if you have to.

The OTHER thing you can try for now is write the function signature like this:

fn from_wav_filename<T>(wav_filename: &str) -> Result<(WaveFmt, AudioFrameReader<T>), ()> 
    where T: io::Read+io::Seek { /* yada yada yada */}

@oscarbailey-xmos
Copy link
Author

Thanks for your help, btw this lib looks very good, it's already been useful for me.

I've tried adding the generic type, the compiler complains I think because in this case the return type can only be one thing i.e. since I'm returning the type returned from audio_frame_reader() it expects the RawChunkReader type

error[E0308]: mismatched types
  --> src/main.rs:79:21
   |
74 | fn from_wav_filename<T>(wav_filename: &str) -> Result<(WaveFmt, AudioFrameReader<T>), ()> 
   |                      - this type parameter
...
79 |         Ok((format, frame_reader))
   |                     ^^^^^^^^^^^^ expected type parameter `T`, found struct `bwavfile::raw_chunk_reader::RawChunkReader`
   |
   = note: expected struct `bwavfile::AudioFrameReader<T>`
              found struct `bwavfile::AudioFrameReader<bwavfile::raw_chunk_reader::RawChunkReader<'_, std::fs::File>>`

error[E0282]: type annotations needed
  --> src/main.rs:88:41
   |
88 |     if let Ok((format, frame_reader)) = from_wav_filename(&wav_filename) {
   |                                         ^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the function `from_wav_filename`

I guess instead of the AudioFrameReader I could return the WaveReader but then I'd lose the state i.e. where I am in the wav file. My use case is that I need a handle to the wav that I can use later, so I read the wav file in then read/seek around the wav using this handle object, which is what it seems the AudioFrameReader is for.

@iluvcapra
Copy link
Owner

So in 09a9413 on master I've changed the interface so this function would work more like...

    fn from_wav_filename(wav_filename: &str) -> Result<(WaveFmt, AudioFrameReader<std::fs::File>), ()> { }

However you will have to rejigger your function a bit because the AudioFrameReader contains the WaveReader by reference.

@iluvcapra
Copy link
Owner

In the future I might revisit this and have AudioFrameReader consume the WaveReader, in which case your function would work.

@iluvcapra
Copy link
Owner

FYI this is implemented in master at 8985361 so your function should work now as you wrote it.

Thanks for the good note, I've been having trouble understanding why you unwrap inner fields on structs in Rust and this was a great example!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants