1use std::cmp::{Eq, Ord, PartialEq, PartialOrd};
2use std::collections::BTreeMap;
3use std::fmt::{Debug, Display, Formatter};
4use std::ops::Range;
5
6use unique_pointer::UniquePointer;
7
8use crate::{Ascii, Match, Matcher, Position, Production, Span, Special, StackRange, State};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct Buffer {
12 input: String,
13 target: String,
14 buffer: String,
15 windows: Vec<String>,
16 succeeded: Vec<Match>,
17 atomic: bool,
18}
19impl Buffer {
20 pub fn new(input: &str, atomic: bool) -> Buffer {
21 Buffer {
22 input: input.to_string(),
23 target: input.to_string(),
24 buffer: String::new(),
25 windows: Vec::<String>::new(),
26 succeeded: Vec::<Match>::new(),
27 atomic,
28 }
29 }
30
31 pub fn produce<T: Matcher>(
32 &mut self,
33 state: &mut State,
34 start: &Position,
35 matcher: T,
36 ) -> Option<Match> {
37 let mut position = start.clone();
38 for c in self.target.chars() {
39 self.buffer.push(c);
40 if let Some(r#match) = matcher.is_match(state.as_mut(), &self.buffer, &position) {
41 self.windows.push(self.buffer.clone());
42 self.succeeded.push(r#match.clone());
43 self.target = self.target.replacen(&self.buffer, "", 1).to_string();
44 self.buffer = String::new();
45 return Some(r#match);
46 } else {
47 if !self.atomic && state.is_epsilon(c) {
48 self.buffer.pop();
49 }
50 }
51 }
52 None
53 }
54
55 pub fn windows(&self) -> Vec<String> {
56 self.windows.clone()
57 }
58
59 pub fn matches(&self) -> Vec<Match> {
60 self.succeeded.clone()
61 }
62}