df_ls_syntax_analysis/token_deserializers/
token_deserialize.rs

1use super::Token;
2use df_ls_diagnostics::DiagnosticsInfo;
3use df_ls_lexical_analysis::TreeCursor;
4
5mod td_allow_empty;
6mod td_any;
7mod td_arg_n;
8mod td_bang_arg_n;
9mod td_bang_arg_n_seq;
10mod td_bool;
11mod td_char;
12mod td_choose;
13mod td_clamp;
14mod td_df_char;
15mod td_df_raw_file;
16mod td_int;
17mod td_option;
18mod td_pipe_arguments;
19mod td_reference;
20mod td_reference_to;
21mod td_string;
22mod td_token;
23mod td_token_argument;
24mod td_tuple;
25mod td_vec;
26
27#[derive(Clone, Debug)]
28pub enum LoopControl {
29    DoNothing,
30    Break,
31    Continue,
32    ErrBreak,
33}
34
35impl Default for LoopControl {
36    fn default() -> Self {
37        LoopControl::DoNothing
38    }
39}
40
41pub trait TokenDeserialize: Sized
42where
43    Self: Default,
44{
45    fn deserialize_tokens(
46        cursor: &mut TreeCursor,
47        source: &str,
48        diagnostics: &mut DiagnosticsInfo,
49    ) -> Result<Box<Self>, ()> {
50        let mut new_self = Box::new(Self::default());
51        loop {
52            let node = cursor.node();
53            // If we reach the limit, stop parsing the file further.
54            if diagnostics.check_message_limit_reached() {
55                crate::mark_rest_of_file_as_unchecked(cursor, diagnostics, &node);
56                break;
57            }
58            match node.kind().as_ref() {
59                "token" => {
60                    match Self::deserialize_general_token(cursor, source, diagnostics, new_self) {
61                        (LoopControl::DoNothing, new_self_result) => {
62                            // Do nothing
63                            new_self = new_self_result;
64                        }
65                        (LoopControl::Break, new_self_result) => {
66                            new_self = new_self_result;
67                            break;
68                        }
69                        (LoopControl::Continue, new_self_result) => {
70                            new_self = new_self_result;
71                            // Only go to next sibling if there is one, if none: break.
72                            // We have reached the end of the file, so have to go up the stack
73                            let new_node = cursor.node();
74                            if new_node.next_sibling().is_none() {
75                                cursor.goto_parent();
76                                break;
77                            }
78                            // If node did not change: break
79                            // This will prevent infinite loops
80                            if new_node == node {
81                                break;
82                            }
83                            continue;
84                        }
85                        (LoopControl::ErrBreak, _new_self_result) => {
86                            return Err(());
87                        }
88                    }
89                }
90                "comment" => {
91                    // Just consume `comment` and move on to next token.
92                    if Token::consume_token(cursor).is_err() {
93                        break;
94                    }
95                }
96                "ERROR" => {
97                    // Can safely be ignored. Diagnostics already added by Lexical Analysis.
98                    if Token::consume_token(cursor).is_err() {
99                        break;
100                    }
101                }
102                "EOF" => break,
103                others => {
104                    log::error!("Found an unknown node of kind: {}", others);
105                    break;
106                }
107            }
108            // If node did not change: break
109            // This will prevent infinite loops
110            let new_node = cursor.node();
111            if new_node == node {
112                break;
113            }
114        }
115        Ok(new_self)
116    }
117
118    fn deserialize_general_token(
119        cursor: &mut TreeCursor,
120        source: &str,
121        diagnostics: &mut DiagnosticsInfo,
122        new_self: Box<Self>,
123    ) -> (LoopControl, Box<Self>);
124
125    fn get_allowed_tokens() -> Option<Vec<String>>;
126
127    /// Should return `Continue` in most cases,
128    /// `DoNothing` in case of String, i32, Tuples and type likes that
129    fn get_vec_loopcontrol() -> LoopControl {
130        LoopControl::Continue
131    }
132}