oom/match/
buffer.rs

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}