I'm still fairly new to rust, but I've been fairly pleased with my progress so far, however, I'm stuck with a particular error that I have no idea where to start looking.
There's a stripped down version below from play.rust-lang, it's from a mini problem I'm working on where I need some conditional buffering of a file depending on the first few lines, I'm sure there is a more idiomatic way of solving my problem, but I want to understand this current error first.
I think my understanding of how traits work is faulty: from below, I'm passing around a source
and rdr
variable, all of which have a trait bound of implementing io::Read
. The general flow is: source bytes/file is passed into EncodingDetector
which implements io::Read
so that it can read the first few lines of the input stream to determine what the encoding is. The encoding is set on ReadBytes
, and the EncodingDetector wrapped stream is passed into it. The ReadBytes
is then stored as the input stream on the SourceFile
, which requires the input stream/source to also implement io::Read
.
Am I missing something simple, or is my understanding of how traits work incomplete?
Thanks!
use std::io;
struct ReadBytes<R, B> {
rdr: R,
buf: B,
}
impl<R: io::Read> ReadBytes<R, Vec<u8>> {
pub fn new(rdr: R) -> ReadBytes<R, Vec<u8>> {
ReadBytes { rdr: rdr, buf: vec![] }
}
}
impl<R: io::Read, B: AsMut<[u8]>> io::Read for ReadBytes<R,B> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.rdr.read(buf)
}
}
struct SourceFile<R>
where
R: io::Read,
{
source: R,
}
impl<R> SourceFile<R>
where
R: io::Read,
{
fn new(source: R) -> SourceFile<R> {
let e = EncodingDetector::new(source);
let rb = ReadBytes::new(e);
//XXX: ReadBytes implements io::Read, why does this complain?
SourceFile { source: rb }
}
}
struct EncodingDetector<R>
where
R: io::Read,
{
source: io::BufReader<R>,
}
impl<R> EncodingDetector<R>
where
R: io::Read,
{
fn new(source: R) -> EncodingDetector<R> {
EncodingDetector { source: io::BufReader::new(source) }
}
}
impl<R> io::Read for EncodingDetector<R>
where
R: io::Read,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.source.read(buf)
}
}
fn main() {
let source = &b"source string"[..];
let s = SourceFile::new(source);
}
Errors:
Compiling playground v0.0.1 (file:///playground)
error[E0308]: mismatched types
--> src/main.rs:37:30
|
37 | SourceFile { source: rb }
| ^^ expected type parameter, found struct `ReadBytes`
|
= note: expected type `R`
found type `ReadBytes<EncodingDetector<R>, std::vec::Vec<u8>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.