oak_rust/lexer/mod.rs
1pub use self::token_type::{RustToken, RustTokenType};
2use crate::language::RustLanguage;
3use oak_core::{Lexer, LexerCache, LexerState, lexer::LexOutput, source::Source};
4
5mod lex;
6mod token_type;
7
8/// A lexer for the Rust programming language.
9///
10/// The `RustLexer` is responsible for tokenizing Rust source code into a sequence of tokens
11/// that can be used by the parser. It handles all Rust syntax including modern features like
12/// raw strings, byte strings, lifetimes, and all standard Rust keywords.
13///
14/// # Examples
15///
16/// Basic usage:
17///
18/// ```rust,ignore
19/// use oak_core::{Lexer, LexerState, SourceText};
20/// use oak_rust::{RustLanguage, RustLexer};
21///
22/// let language = RustLanguage::default();
23/// let lexer = RustLexer::new(&language);
24/// let source = SourceText::new("fn main() { println!(\"Hello, world!\"); }");
25/// let output = lexer.lex(source, 0);
26///
27/// // The output contains tokens for the entire source code
28/// assert!(!output.tokens.is_empty());
29/// ```
30///
31/// Tokenizing different Rust constructs:
32///
33/// ```rust,ignore
34/// use oak_core::{Lexer, LexerState, SourceText};
35/// use oak_rust::{RustLanguage, RustLexer};
36///
37/// let language = RustLanguage::default();
38/// let lexer = RustLexer::new(&language);
39///
40/// // Tokenize a function with various Rust features
41/// let source = SourceText::new(
42/// r#"
43/// fn calculate<'a>(x: &'a i32, y: i32) -> i32 {
44/// let result = x + y;
45/// println!("Result: {}", result);
46/// result
47/// }
48/// "#,
49/// );
50/// let output = lexer.lex(source, 0);
51///
52/// // Verify that tokens were generated
53/// assert!(output.tokens.len() > 10);
54/// ```
55#[derive(Clone)]
56pub struct RustLexer<'config> {
57 _config: &'config RustLanguage,
58}
59
60type State<'a, S> = LexerState<'a, S, RustLanguage>;
61
62impl<'config> Lexer<RustLanguage> for RustLexer<'config> {
63 fn lex<'a, S: Source + ?Sized>(&self, source: &'a S, _edits: &[oak_core::TextEdit], cache: &'a mut impl LexerCache<RustLanguage>) -> LexOutput<RustLanguage> {
64 let mut state = State::new_with_cache(source, 0, cache);
65 let result = self.run(&mut state);
66 if result.is_ok() {
67 state.add_eof();
68 }
69 state.finish_with_cache(result, cache)
70 }
71}
72
73impl<'config> RustLexer<'config> {
74 /// Creates a new `RustLexer` with the given language configuration.
75 ///
76 /// # Parameters
77 ///
78 /// * `config` - A reference to the `RustLanguage` configuration that controls
79 /// language-specific parsing behavior.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// # use oak_rust::{RustLexer, RustLanguage};
85 ///
86 /// let language = RustLanguage::default();
87 /// let lexer = RustLexer::new(&language);
88 /// ```
89 pub fn new(config: &'config RustLanguage) -> Self {
90 Self { _config: config }
91 }
92
93 /// Internal method to run the lexer on the given state.
94 /// This delegates to the implementation in the `lex` module.
95 pub(crate) fn run<'s, S: Source + ?Sized>(&self, state: &mut LexerState<'s, S, RustLanguage>) -> Result<(), oak_core::OakError> {
96 lex::run(self, state)
97 }
98}