This is a follow-on to [Solved] Trouble with Peekable and SkipWhile structs
I'm now trying to refactor the code in that post like so:
use std::iter::{Iterator, Peekable, SkipWhile};
use std::ops::Fn;
use std::str::Chars;
use std::string::String;
struct Parser<'a, I: 'a>
where
I: Iterator<Item=char>
{
chars: &'a I,
}
impl<'a, I, P> Parser<'a, Peekable<SkipWhile<I, P>>>
where
I: Iterator<Item=char>,
P: Fn(&char) -> bool
{
fn from_string(string: &String) -> Parser<Peekable<SkipWhile<Chars, P>>> {
Parser {
chars: &string
.chars()
.skip_while(|c| match *c {
'"' => true,
_ => false,
})
.peekable()
}
}
fn collect_and_unescape(&mut self, value: &mut String) {
loop {
let next = self.chars.next();
let next_char = match next {
Some('\\') => {
match self.chars.peek() {
Some(&'"') | Some(&'\\') => self.chars.next(),
_ => None,
}
}
Some('"') | None => break,
_ => next,
};
if let Some(c) = next_char {
value.push(c);
}
}
}
fn skip_chars_while<C>(&mut self, predicate: C)
where
C: Fn(Option<&char>) -> bool
{
loop {
if predicate(self.chars.peek()) {
self.chars.next();
} else {
break;
}
}
}
}
impl<'a, I, P> Iterator for Parser<'a, Peekable<SkipWhile<I, P>>>
where
I: Iterator<Item=char>,
P: Fn(&char) -> bool
{
type Item = (String, String);
fn next(&mut self) -> Option<Self::Item> {
if self.chars.peek() == None {
return None;
}
let mut key = String::new();
let mut value = String::new();
self.collect_and_unescape(&mut key);
self.skip_chars_while(|c| match c {
Some(&'"') => false,
_ => true,
});
Some((key, value))
}
}
fn main() {
let s = String::from("\"hell\\\"o_world\"=>\"value\\\" with quotes\"");
let mut chars = s.chars()
.skip_while(|c| match *c {
'"' => true,
_ => false,
})
.peekable();
let mut key = String::new();
let mut value = String::new();
//collect_and_unescape(&mut key, &mut chars);
let mut chars = chars.skip_while(|c| match *c {
'"' => false,
_ => true,
}).peekable();
chars.next();
//collect_and_unescape(&mut value, &mut chars);
//match chars.peek() {
// Some(&',') | Some(' ') =>
//}
println!("key: {}, value: {}", key, value);
let mut chars = chars.skip_while(|c| match *c {
'"' => false,
_ => true,
}).peekable();
}
But when I compile it I get mismatched types because SkipWhile
is expecting P
and getting a closure:
❯❯❯ rustc test.rs
error[E0308]: mismatched types
--> test.rs:20:9
|
20 | / Parser {
21 | | chars: &string
22 | | .chars()
23 | | .skip_while(|c| match *c {
... |
27 | | .peekable()
28 | | }
| |_________^ expected type parameter, found closure
|
= note: expected type `Parser<'_, std::iter::Peekable<std::iter::SkipWhile<std::str::Chars<'_>, P>>>`
found type `Parser<'_, std::iter::Peekable<std::iter::SkipWhile<std::str::Chars<'_>, [closure@test.rs:23:29: 26:18]>>>`
error: aborting due to previous error(s)
I'm at a loss for how to resolve this. I think I'm doing the correct thing, but then again, I was also apparently misunderstanding how to impl my Parser
since I thought the iterator trait would be good enough instead of having to specify Peekable<SkipWhile<std::str::Chars, ...>>
.
Help and advice on better ways to do this is greatly appreciated.