logos/
internal.rs

1use crate::source::Chunk;
2use crate::{Filter, FilterResult, Lexer, Logos, Skip};
3
4/// Trait used by the functions contained in the `Lexicon`.
5///
6/// # WARNING!
7///
8/// **This trait, and its methods, are not meant to be used outside of the
9/// code produced by `#[derive(Logos)]` macro.**
10pub trait LexerInternal<'source> {
11    type Token: Logos<'source>;
12
13    /// Read a chunk at current position.
14    fn read<T: Chunk<'source>>(&self) -> Option<T>;
15
16    /// Read a chunk at current position, offset by `n`.
17    fn read_at<T: Chunk<'source>>(&self, n: usize) -> Option<T>;
18
19    /// Unchecked read a byte at current position, offset by `n`.
20    #[cfg(not(feature = "forbid_unsafe"))]
21    unsafe fn read_byte_unchecked(&self, n: usize) -> u8;
22
23    /// Checked read a byte at current position, offset by `n`.
24    #[cfg(feature = "forbid_unsafe")]
25    fn read_byte(&self, n: usize) -> u8;
26
27    /// Test a chunk at current position with a closure.
28    fn test<T: Chunk<'source>, F: FnOnce(T) -> bool>(&self, test: F) -> bool;
29
30    /// Bump the position by `size`.
31    fn bump_unchecked(&mut self, size: usize);
32
33    /// Reset `token_start` to `token_end`.
34    fn trivia(&mut self);
35
36    /// Set the current token to appropriate `#[error]` variant.
37    /// Guarantee that `token_end` is at char boundary for `&str`.
38    fn error(&mut self);
39
40    fn end(&mut self);
41
42    fn set(
43        &mut self,
44        token: Result<
45            Self::Token,
46            <<Self as LexerInternal<'source>>::Token as Logos<'source>>::Error,
47        >,
48    );
49}
50
51pub trait CallbackResult<'s, P, T: Logos<'s>> {
52    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
53    where
54        Constructor: Fn(P) -> T;
55}
56
57impl<'s, P, T: Logos<'s>> CallbackResult<'s, P, T> for P {
58    #[inline]
59    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
60    where
61        Constructor: Fn(P) -> T,
62    {
63        lex.set(Ok(c(self)))
64    }
65}
66
67impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for bool {
68    #[inline]
69    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
70    where
71        Constructor: Fn(()) -> T,
72    {
73        match self {
74            true => lex.set(Ok(c(()))),
75            false => lex.set(Err(T::Error::default())),
76        }
77    }
78}
79
80impl<'s, P, T: Logos<'s>> CallbackResult<'s, P, T> for Option<P> {
81    #[inline]
82    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
83    where
84        Constructor: Fn(P) -> T,
85    {
86        match self {
87            Some(product) => lex.set(Ok(c(product))),
88            None => lex.set(Err(T::Error::default())),
89        }
90    }
91}
92
93impl<'s, P, E, T: Logos<'s>> CallbackResult<'s, P, T> for Result<P, E>
94where
95    E: Into<T::Error>,
96{
97    #[inline]
98    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
99    where
100        Constructor: Fn(P) -> T,
101    {
102        match self {
103            Ok(product) => lex.set(Ok(c(product))),
104            Err(err) => lex.set(Err(err.into())),
105        }
106    }
107}
108
109impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for Skip {
110    #[inline]
111    fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
112    where
113        Constructor: Fn(()) -> T,
114    {
115        lex.trivia();
116        T::lex(lex);
117    }
118}
119
120impl<'s, E, T: Logos<'s>> CallbackResult<'s, (), T> for Result<Skip, E>
121where
122    E: Into<T::Error>,
123{
124    #[inline]
125    fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
126    where
127        Constructor: Fn(()) -> T,
128    {
129        match self {
130            Ok(_) => {
131                lex.trivia();
132                T::lex(lex);
133            }
134            Err(err) => lex.set(Err(err.into())),
135        }
136    }
137}
138
139impl<'s, P, T: Logos<'s>> CallbackResult<'s, P, T> for Filter<P> {
140    #[inline]
141    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
142    where
143        Constructor: Fn(P) -> T,
144    {
145        match self {
146            Filter::Emit(product) => lex.set(Ok(c(product))),
147            Filter::Skip => {
148                lex.trivia();
149                T::lex(lex);
150            }
151        }
152    }
153}
154
155impl<'s, P, E, T: Logos<'s>> CallbackResult<'s, P, T> for FilterResult<P, E>
156where
157    E: Into<T::Error>,
158{
159    fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
160    where
161        Constructor: Fn(P) -> T,
162    {
163        match self {
164            FilterResult::Emit(product) => lex.set(Ok(c(product))),
165            FilterResult::Skip => {
166                lex.trivia();
167                T::lex(lex);
168            }
169            FilterResult::Error(err) => lex.set(Err(err.into())),
170        }
171    }
172}
173
174impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for T {
175    #[inline]
176    fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
177    where
178        Constructor: Fn(()) -> T,
179    {
180        lex.set(Ok(self))
181    }
182}
183
184impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for Result<T, T::Error> {
185    #[inline]
186    fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
187    where
188        Constructor: Fn(()) -> T,
189    {
190        match self {
191            Ok(product) => lex.set(Ok(product)),
192            Err(err) => lex.set(Err(err)),
193        }
194    }
195}
196
197impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for Filter<T> {
198    #[inline]
199    fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
200    where
201        Constructor: Fn(()) -> T,
202    {
203        match self {
204            Filter::Emit(product) => lex.set(Ok(product)),
205            Filter::Skip => {
206                lex.trivia();
207                T::lex(lex);
208            }
209        }
210    }
211}
212
213impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for FilterResult<T, T::Error> {
214    fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
215    where
216        Constructor: Fn(()) -> T,
217    {
218        match self {
219            FilterResult::Emit(product) => lex.set(Ok(product)),
220            FilterResult::Skip => {
221                lex.trivia();
222                T::lex(lex);
223            }
224            FilterResult::Error(err) => lex.set(Err(err)),
225        }
226    }
227}