Hi!
I'm having a bit of an issue with a bit of Rust code regarding traits and associated typed. I've recently been trying to take more advantage of traits, but I've run into an issue which I can't figure out.
I have the following code:
pub struct Block {
id: String,
tokens: Vec<Token>,
current_reader: Box<dyn TokenReader<Error = ParseError>>,
}
impl Block {
pub fn new() -> Self {
Self {
id: "".to_string(),
tokens: vec![],
current_reader: Box::new(ArgumentReader::new()),
}
}
}
But the issue seems to be with the associated type for the dyn TokenReader<Error = ParseError>
. When I try to compile the code I get the following error:
error[E0271]: type mismatch resolving `<ArgumentReader as Reader<char, Token>>::Error == Infallible`
--> src\mcfunction_file\block.rs:33:29
|
33 | current_reader: Box::new(ArgumentReader::new()),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<ArgumentReader as Reader<char, Token>>::Error == Infallible`
|
note: expected this to be `Infallible`
--> src\mcfunction_file\block\readers\argument_reader.rs:16:18
|
16 | type Error = ParseError;
| ^^^^^^^^^^
= note: required for the cast from `readers::argument_reader::ArgumentReader` to the object type `dyn TokenReader<Error = Infallible>`
I'm confused by the fact that it says that there is a mismatch because the Error
type is expected to be Infallible
, but I thought I set the type to be ParseError
.
The TokenReader
trait has the following code:
pub trait TokenReader: CharReader<Token> {
fn new() -> Self
where
Self: Sized;
}
The CharReader
code looks like this:
pub trait CharReader<R> : Reader<char, R> {
// TODO look into accepting `impl Into<String>` in some way
fn read_string(mut self, string: String) -> Result<R, Self::Error>
where Self: Sized {
self.read_iter(string.chars().into_iter().collect())
}
}
And lastly this is the code for the reader
trait:
/// A reader accepts incremental inputs until it's done reading.
pub trait Reader<I, R> {
type Error;
/// When this returns `true` the reader indicates that the reader is done and [read] should not
/// be called anymore. If this returns `false` it indicates that the reader is willing to accept
/// input using the [read] function.
fn done(&self, input: &I) -> Result<bool, Self::Error>;
/// Reads and processes the given input.
fn read(&mut self, input: I) -> Result<(), Self::Error>;
/// Returns the result of the input and does any needed cleanup.
fn get_result(self) -> Result<R, Self::Error>;
// TODO look into accepting `impl Iterator<Item = I>` in some way
/// Reads an iterator until the reader is done.
fn read_iter(mut self, iter: Vec<I>) -> Result<R, Self::Error>
where Self : Sized
{
for item in iter {
if self.done(&item)? {
break;
}
self.read(item)?;
}
self.get_result()
}
}
If anyone could give me some pointers I would really appreciate it.