luau_parser/types/
traits.rs

1//! Module holding all trait definitions in this crate.
2
3use luau_lexer::prelude::{Lexer, Error, Token};
4use lsp_types::Range;
5
6/// A trait to print the token as-is, while preserving all user spaces, comments
7/// and styling.
8pub trait Print {
9    /// Prints only the very final trivia. Used for the default implementation of
10    /// [`Print::print`], which just joins [`Print::print_without_final_trivia`]
11    /// and this function.
12    fn print_final_trivia(&self) -> String;
13
14    /// Prints the whole token including all surrounding trivia, excluding the
15    /// very last trailing trivia.
16    fn print_without_final_trivia(&self) -> String;
17
18    /// Prints the whole token including all surrounding trivia.
19    #[inline]
20    fn print(&self) -> String {
21        self.print_without_final_trivia() + &self.print_final_trivia()
22    }
23}
24
25/// A trait that to parse this struct from a [`lexer`](Lexer) and starting with
26/// a specific [`token`](Token).
27pub trait Parse<O = Self> {
28    /// Try parsing the current item, starting from the passed token.
29    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<O>;
30}
31
32/// A wrapper trait for [`Parse`] where it would reset the lexer's state upon
33/// failure.
34pub trait TryParse<O = Self>
35where
36    O: Parse<O>,
37{
38    /// Try parsing and reset the lexer's state upon failure.
39    fn try_parse(lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<O> {
40        let state = lexer.save_state();
41
42        match O::parse(lexer.next_token(), lexer, errors) {
43            value @ Some(_) => value,
44            None => {
45                lexer.set_state(state);
46
47                None
48            }
49        }
50    }
51}
52
53/// A trait that to parse this struct from a [`lexer`](Lexer) and starting with
54/// a specific [`token`](Token) and with specific arguments.
55pub trait ParseWithArgs<T, O = Self> {
56    /// Try parsing the current item, starting from the passed token with the
57    /// passed arguments.
58    fn parse_with(
59        token: Token,
60        lexer: &mut Lexer,
61        errors: &mut Vec<Error>,
62        args: T,
63    ) -> Option<O>;
64}
65
66/// A wrapper trait for [`ParseWithArgs`] where it would reset the lexer's state
67/// upon failure.
68pub trait TryParseWithArgs<T, O = Self, O2 = O>
69where
70    O2: ParseWithArgs<T, O>,
71{
72    /// Try parsing and reset the lexer's state upon failure.
73    #[inline]
74    fn try_parse_with(lexer: &mut Lexer, errors: &mut Vec<Error>, args: T) -> Option<O> {
75        let state = lexer.save_state();
76
77        match O2::parse_with(lexer.next_token(), lexer, errors, args) {
78            value @ Some(_) => value,
79            None => {
80                lexer.set_state(state);
81
82                None
83            }
84        }
85    }
86}
87
88/// Errors that may occur during [`get_range`](GetRangeError). They should
89/// never happen if [`Cst.status`](crate::types::Cst::status) is
90/// [`AstStatus::Complete`](crate::types::AstStatus::Complete).
91#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
92#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
93pub enum GetRangeError {
94    /// This is an `ERROR` variant and thus spans no range in the source code.
95    ErrorVariant,
96
97    /// This is an empty list and thus spans no range in the source code.
98    EmptyList,
99
100    /// This is an empty block and thus spans no range in the source code.
101    EmptyBlock,
102
103    /// This is either
104    /// * [`TableKey::UndefinedString`](crate::types::TableKey::UndefinedString), or
105    /// * [`TableKey::UndefinedNumber`](crate::types::TableKey::UndefinedNumber)
106    ///
107    /// which don't actually exist in the source code and are added by the parser.
108    UndefinedKey,
109}
110
111/// A trait for getting the range for this specific item.
112pub trait GetRange {
113    /// Get the range of the node.
114    ///
115    /// # Errors
116    ///
117    /// This will only fail if [`Cst.status`](crate::types::Cst::status) is
118    /// [`AstStatus::HasErrors`](crate::types::AstStatus::HasErrors).
119    fn get_range(&self) -> Result<Range, GetRangeError>;
120}