luau_parser/types/
traits.rs

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