regress/
cursor.rs

1use crate::bytesearch::ByteSeq;
2use crate::indexing::InputIndexer;
3
4#[derive(Debug, Copy, Clone)]
5pub struct Forward;
6
7#[derive(Debug, Copy, Clone)]
8pub struct Backward;
9
10pub trait Direction: core::fmt::Debug + Copy + Clone {
11    const FORWARD: bool;
12    fn new() -> Self;
13}
14
15impl Direction for Forward {
16    const FORWARD: bool = true;
17    #[inline(always)]
18    fn new() -> Self {
19        Forward {}
20    }
21}
22
23impl Direction for Backward {
24    const FORWARD: bool = false;
25    #[inline(always)]
26    fn new() -> Self {
27        Backward {}
28    }
29}
30
31/// \return whether we match some literal bytes.
32/// If so, update the position. If not, the position is unspecified.
33#[inline(always)]
34pub fn try_match_lit<Input: InputIndexer, Dir: Direction, Bytes: ByteSeq>(
35    input: &Input,
36    dir: Dir,
37    pos: &mut Input::Position,
38    bytes: &Bytes,
39) -> bool {
40    input.match_bytes(dir, pos, bytes)
41}
42
43/// \return the next character, updating the position.
44#[inline(always)]
45pub fn next<Input: InputIndexer, Dir: Direction>(
46    input: &Input,
47    _dir: Dir,
48    pos: &mut Input::Position,
49) -> Option<Input::Element> {
50    if Dir::FORWARD {
51        input.next_right(pos)
52    } else {
53        input.next_left(pos)
54    }
55}
56
57/// \return the next *byte*, or None if at the end, updating the position.
58/// Note this may break UTF8 sequences.
59#[inline(always)]
60pub fn next_byte<Input: InputIndexer, Dir: Direction>(
61    input: &Input,
62    _dir: Dir,
63    pos: &mut Input::Position,
64) -> Option<u8> {
65    assert!(
66        Input::CODE_UNITS_ARE_BYTES,
67        "Not implemented for non-byte input"
68    );
69    let res;
70    if Dir::FORWARD {
71        res = input.peek_byte_right(*pos);
72        *pos += if res.is_some() { 1 } else { 0 };
73    } else {
74        res = input.peek_byte_left(*pos);
75        *pos -= if res.is_some() { 1 } else { 0 };
76    }
77    res
78}