Hello everyone! A Python guy here, trying out Rust (begging pardon for any pythonisms!)
I'm writing a JSON parser as a learning project, and as a very first step I tried to create an iterator that would read a file in chunks of a pre-defined size and simply yield them to a consumer (the next step is to extract lexemes from those chunks but I'm just doing baby steps for now…)
I ended up with some mostly working code and I'd like to have a sanity check on that, please! Here's the code:
struct Lexer {
buf: [u8; BUFSIZE],
f: File,
}
impl Iterator for Lexer {
type Item = String;
fn next(&mut self) -> Option<String> {
match self.f.read(&mut self.buf) {
Err(error) => panic!("Can't read: {}", error),
Ok(0) => None,
Ok(result) => Some(str::from_utf8(&self.buf[0..result]).unwrap().to_string()),
}
}
}
fn lexer(filename: &str) -> Lexer {
Lexer {
buf: [0; BUFSIZE],
f: match File::open(filename) {
Err(error) => panic!("Can't open {}: {}", filename, error),
Ok(result) => result,
},
}
}
A few questions:
- Is this whole approach idiomatic in Rust at all? I mean, having a lexer that you could iterate as
for lexeme in lexer("somefile")
? - My
Lexer
struct has astd::fs::File
field but what I actuall need is anything implementingstd::io::Read
. I know I can declare the struct asLexer<T: Read> { f: T }
but then I can't quite figure out the syntax for the trait implementation and the fabric function. - How to declare the type for an Iterator to be
&str
(there's no need to create full-blown strings anyway)?
Thanks!