Skip to main content

peek/
peek.rs

1use elyze::errors::ParseResult;
2use elyze::matcher::Match;
3use elyze::peek::{peek, PeekResult, Peekable};
4use elyze::recognizer::Recognizable;
5use elyze::scanner::Scanner;
6
7struct CloseParentheses;
8
9impl Match<u8> for CloseParentheses {
10    fn is_matching(&self, data: &[u8]) -> (bool, usize) {
11        if data[0] == b')' {
12            (true, 1)
13        } else {
14            (false, 0)
15        }
16    }
17
18    fn size(&self) -> usize {
19        1
20    }
21}
22
23struct ParenthesesGroup;
24
25impl<'a> Peekable<'a, u8> for ParenthesesGroup {
26    fn peek(&self, scanner: &Scanner<'a, u8>) -> ParseResult<PeekResult> {
27        // create an internal scanner allowing to peek data without alterating the original scanner
28        let mut inner_scanner = Scanner::new(&scanner.remaining());
29
30        // loop on each byte until we find a close parenthesis
31        loop {
32            if inner_scanner.is_empty() {
33                // we have reached the end without finding a close parenthesis
34                break;
35            }
36            if CloseParentheses.recognize(&mut inner_scanner)?.is_some() {
37                // we have found a close parenthesis
38                return Ok(PeekResult::Found {
39                    // we return the position of the close parenthesis
40                    end_slice: inner_scanner.current_position(),
41                    // our peeking doesn't include a start element
42                    start_element_size: 0,
43                    // the size of the end element is a close parenthesis of 1 byte
44                    end_element_size: 1,
45                });
46            }
47
48            // consume the current byte
49            inner_scanner.bump_by(1);
50        }
51
52        // At this point, we have reached the end of available data without finding a close parenthesis
53        Ok(PeekResult::NotFound)
54    }
55}
56
57fn main() -> ParseResult<()> {
58    let data = b"7 * ( 1 + 2 )";
59    let mut scanner = Scanner::new(data);
60    scanner.bump_by(5); // consumes : 7 * (
61    let result = peek(ParenthesesGroup, &scanner)?;
62    if let Some(peeking) = result {
63        println!(
64            "{:?}",
65            // the peek_slice method returns the slice of recognized without the end element
66            String::from_utf8_lossy(peeking.peeked_slice()) // 1 + 2
67        );
68    } else {
69        println!("not found");
70    }
71    println!(
72        "scanner: {:?}",
73        // the scanner itself remains unchanged
74        String::from_utf8_lossy(scanner.remaining()) // scanner: " 1 + 2 )"
75    );
76    Ok(())
77}