1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::io::{Read, Bytes};
use std::io::Result;
const ESCAPE_CHAR: u8 = '\\' as u8;
const CHAR_DOUBLE_QUOTE: u8 = '"' as u8;
const ARRAY_OPEN: u8 = '[' as u8;
const ARRAY_CLOSE: u8 = ']' as u8;
const OBJECT_OPEN: u8 = '{' as u8;
const OBJECT_CLOSE: u8 = '}' as u8;
pub struct LevelReader<R> where R:Read {
level:u32,
target_level: u32,
read:Bytes<R>,
in_string:bool,
escape:bool
}
impl<R> Iterator for LevelReader<R>
where R: Read {
type Item = Result<Vec<u8>>;
fn next(&mut self) -> Option<Self::Item> {
let mut next_char_result = self.read.next();
let mut pre = true;
let mut result:Vec<u8> = Vec::new();
while !next_char_result.is_none() && (pre || self.level > self.target_level) {
match next_char_result.unwrap() {
Err(e) => return Some(Err(e)),
Ok(b) => {
if self.escape {
self.escape = false;
} else if self.in_string && b == ESCAPE_CHAR {
self.escape = true;
} else if self.in_string && b == CHAR_DOUBLE_QUOTE {
self.in_string = false;
} else if !self.in_string && b == CHAR_DOUBLE_QUOTE {
self.in_string = true;
} else if !self.in_string && (b == ARRAY_OPEN || b == OBJECT_OPEN) {
self.level += 1;
if pre && self.level > self.target_level {
pre = false;
}
} else if !self.in_string && (b == ARRAY_CLOSE || b == OBJECT_CLOSE) {
self.level -= 1;
}
if !pre { result.push(b); };
}
}
next_char_result = self.read.next();
}
if result.is_empty() {
None
} else {
Some(Ok(result))
}
}
}
impl <R> LevelReader<R> where R:Read {
pub fn new(r: R, target_level:u32) -> LevelReader<R> {
LevelReader {
level: 0,
read: r.bytes(),
in_string: false,
escape: false,
target_level
}
}
}