1use super::{Tree, EndOfFile, Location, Token, Stream};
4
5pub const MISSING_OPEN: &'static str = "Unmatched close bracket";
6pub const MISSING_CLOSE: &'static str = "Unmatched open bracket";
7
8#[derive(Debug)]
17pub struct Round(pub Vec<Token>);
18
19impl Round {
20 pub fn new(contents: Vec<Token>) -> Box<Self> { Box::new(Self(contents)) }
21}
22
23impl Tree for Round {}
24
25#[derive(Debug)]
32pub struct Square(pub Vec<Token>);
33
34impl Square {
35 pub fn new(contents: Vec<Token>) -> Box<Self> { Box::new(Self(contents)) }
36}
37
38impl Tree for Square {}
39
40#[derive(Debug)]
46pub struct Brace(pub Vec<Token>);
47
48impl Brace {
49 pub fn new(contents: Vec<Token>) -> Box<Self> { Box::new(Self(contents)) }
50}
51
52impl Tree for Brace {}
53
54pub struct Brackets<F, I> {
62 open: char,
63 close: char,
64 new_bracket: F,
65 input: I,
66 depth: usize
67}
68
69impl<
70 F: Fn(Vec<Token>) -> Box<dyn Tree>,
71 I: Stream,
72> Brackets<F, I> {
73 pub fn new(open: char, close: char, new_bracket: F, input: I) -> Self {
80 Self {open, close, new_bracket, input, depth: 0}
81 }
82
83 fn parse_bracket(&mut self, open_loc: Location) -> Token {
85 let mut contents: Vec<Token> = Vec::new();
86 loop {
87 let token = self.read();
88 if token.is_incomplete() { return token; }
89 if token == EndOfFile { return Token::new_err(MISSING_CLOSE, open_loc); }
90 if token == self.close {
91 let close_loc = token.location();
92 let bracket = (&self.new_bracket)(contents);
93 return Token::new(bracket, Location {start: open_loc.start, end: close_loc.end});
94 }
95 contents.push(token);
96 }
97 }
98}
99
100impl<
101 F: Fn(Vec<Token>) -> Box<dyn Tree>,
102 I: Stream,
103> Stream for Brackets<F, I> {
104 fn read(&mut self) -> Token {
105 let token = self.input.read();
106 if token == self.open {
107 self.depth += 1;
108 return self.parse_bracket(token.location());
109 }
110 if token == self.close {
111 if self.depth == 0 {
112 return Token::new_err(MISSING_OPEN, token.location());
113 }
114 self.depth -= 1;
115 }
116 token
117 }
118}
119
120#[cfg(test)]
123mod tests {
124 use crate::{Characters};
125 use super::*;
126
127 #[test]
128 fn some_brackets() {
129 let mut parser = Brackets::new(
130 '(',
131 ')',
132 |contents| Box::new(Round(contents)),
133 Brackets::new(
134 '{',
135 '}',
136 |contents| Box::new(Brace(contents)),
137 Characters::new("(a{b}(cd)){}", true)
138 )
139 );
140 let mut contents1 = parser.read().unwrap::<Round>().0.into_iter();
141 assert_eq!(contents1.read(), 'a');
142 let mut contents2 = contents1.read().unwrap::<Brace>().0.into_iter();
143 assert_eq!(contents2.read(), 'b');
144 assert_eq!(contents2.read(), EndOfFile);
145 let mut contents2 = contents1.read().unwrap::<Round>().0.into_iter();
146 assert_eq!(contents2.read(), 'c');
147 assert_eq!(contents2.read(), 'd');
148 assert_eq!(contents2.read(), EndOfFile);
149 assert_eq!(contents1.read(), EndOfFile);
150 let mut contents1 = parser.read().unwrap::<Brace>().0.into_iter();
151 assert_eq!(contents1.read(), EndOfFile);
152 assert_eq!(parser.read(), EndOfFile);
153 }
154
155 #[test]
156 fn inside_out() {
157 fn noop(parser: impl Stream) -> impl Stream { parser }
159
160 fn round(parser: impl Stream) -> impl Stream {
162 noop(Brackets::new('(', ')', |contents| {
163 let contents = noop(contents.into_iter()).read_all();
164 Box::new(Round(contents))
165 }, parser))
166 }
167
168 fn square(parser: impl Stream) -> impl Stream {
170 round(Brackets::new('[', ']', |contents| {
171 let contents = round(contents.into_iter()).read_all();
172 Box::new(Square(contents))
173 }, parser))
174 }
175
176 fn brace(parser: impl Stream) -> impl Stream {
178 square(Brackets::new('{', '}', |contents| {
179 let contents = square(contents.into_iter()).read_all();
180 Box::new(Brace(contents))
181 }, parser))
182 }
183
184 let mut parser = brace(Characters::new("a{b[c(d(e[f{g}]))]}", true));
185 assert_eq!(parser.read(), 'a');
186 let mut contents1 = parser.read().unwrap::<Brace>().0.into_iter();
187 assert_eq!(contents1.read(), 'b');
188 let mut contents2 = contents1.read().unwrap::<Square>().0.into_iter();
189 assert_eq!(contents2.read(), 'c');
190 let mut contents3 = contents2.read().unwrap::<Round>().0.into_iter();
191 assert_eq!(contents3.read(), 'd');
192 let mut contents4 = contents3.read().unwrap::<Round>().0.into_iter();
193 assert_eq!(contents4.read(), 'e');
194 let mut contents5 = contents4.read().unwrap::<Square>().0.into_iter();
195 assert_eq!(contents5.read(), 'f');
196 let mut contents6 = contents5.read().unwrap::<Brace>().0.into_iter();
197 assert_eq!(contents6.read(), 'g');
198 assert_eq!(contents6.read(), EndOfFile);
199 assert_eq!(contents5.read(), EndOfFile);
200 assert_eq!(contents4.read(), EndOfFile);
201 assert_eq!(contents3.read(), EndOfFile);
202 assert_eq!(contents2.read(), EndOfFile);
203 assert_eq!(contents1.read(), EndOfFile);
204 assert_eq!(parser.read(), EndOfFile);
205 }
206}