df_ls_syntax_analysis/token_deserializers/token_deserialize/
td_allow_empty.rs

1use super::super::{Token, TokenArgument, TryFromArgumentGroup};
2use super::TokenDeserialize;
3use df_ls_core::AllowEmpty;
4use df_ls_diagnostics::DiagnosticsInfo;
5
6// Deserialize a token with following pattern: `[REF:AllowEmpty<T>]`
7crate::token_deserialize_unary_token!(AllowEmpty<T>, T);
8
9// ------------------------- Convert a group of arguments to Self -----------------------
10
11impl<T> TryFromArgumentGroup for AllowEmpty<T>
12where
13    T: TryFromArgumentGroup,
14{
15    fn try_from_argument_group(
16        token: &mut Token,
17        source: &str,
18        diagnostics: &mut DiagnosticsInfo,
19        add_diagnostics_on_err: bool,
20    ) -> Result<Self, ()> {
21        token.check_as_required_argument(source, diagnostics, add_diagnostics_on_err)?;
22        let arg_opt = token.get_current_arg_opt();
23        if let Some(arg) = arg_opt {
24            match arg.value {
25                TokenArgument::TVEmpty => {
26                    token.consume_argument();
27                    Ok(AllowEmpty::None)
28                }
29                _ => {
30                    match T::try_from_argument_group(
31                        token,
32                        source,
33                        diagnostics,
34                        add_diagnostics_on_err,
35                    ) {
36                        Ok(value) => Ok(AllowEmpty::Some(value)),
37                        Err(_) => Err(()),
38                    }
39                }
40            }
41        } else {
42            token.consume_argument();
43            Err(())
44        }
45    }
46}
47
48// -------------------------Convert one argument to Self -----------------------
49// TryFromArgument is not used, use TryFromArgumentGroup instead
50
51// ---------------------------- TESTS --------------------------
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::test_tree_structure;
56    use crate::test_utils::SyntaxTestBuilder;
57    use df_ls_diagnostics::{Position, Range};
58    use df_ls_lexical_analysis::test_utils::LexerTestBuilder;
59
60    #[test]
61    fn test_allow_empty_string_correct() {
62        let test_builder = SyntaxTestBuilder::from_lexer_test_builder(
63            LexerTestBuilder::test_source(
64                "header
65                [REF:optional string]
66                [REF:]",
67            )
68            .add_test_lexer_diagnostics_codes(vec![])
69            .add_test_lexer_diagnostics_ranges(vec![]),
70        )
71        .add_test_syntax_diagnostics_codes(vec![])
72        .add_test_syntax_diagnostics_ranges(vec![]);
73
74        test_tree_structure!(
75            test_builder,
76            [
77                AllowEmpty<String> => AllowEmpty::Some("optional string".to_owned()),
78                AllowEmpty<String> => AllowEmpty::None,
79            ]
80        );
81    }
82
83    #[test]
84    fn test_allow_empty_string_to_many_args() {
85        let test_builder = SyntaxTestBuilder::<bool>::from_lexer_test_builder(
86            LexerTestBuilder::test_source(
87                "header
88                [REF::]",
89            )
90            .add_test_lexer_diagnostics_codes(vec![])
91            .add_test_lexer_diagnostics_ranges(vec![]),
92        )
93        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_number"])
94        .add_test_syntax_diagnostics_ranges(vec![Range {
95            start: Position {
96                line: 1,
97                character: 16,
98            },
99            end: Position {
100                line: 1,
101                character: 23,
102            },
103        }]);
104
105        test_tree_structure!(
106            test_builder,
107            [
108                AllowEmpty<String> =!,
109            ]
110        );
111    }
112
113    #[test]
114    fn test_allow_empty_string_to_few_args() {
115        let test_builder = SyntaxTestBuilder::<bool>::from_lexer_test_builder(
116            LexerTestBuilder::test_source(
117                "header
118                [REF]",
119            )
120            .add_test_lexer_diagnostics_codes(vec![])
121            .add_test_lexer_diagnostics_ranges(vec![]),
122        )
123        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_number"])
124        .add_test_syntax_diagnostics_ranges(vec![Range {
125            start: Position {
126                line: 1,
127                character: 16,
128            },
129            end: Position {
130                line: 1,
131                character: 21,
132            },
133        }]);
134
135        test_tree_structure!(
136            test_builder,
137            [
138                AllowEmpty<String> =!,
139            ]
140        );
141    }
142
143    #[test]
144    fn test_allow_empty_string_wrong_arg_type() {
145        let test_builder = SyntaxTestBuilder::<bool>::from_lexer_test_builder(
146            LexerTestBuilder::test_source(
147                "header
148                [REF:56]",
149            )
150            .add_test_lexer_diagnostics_codes(vec![])
151            .add_test_lexer_diagnostics_ranges(vec![]),
152        )
153        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_type"])
154        .add_test_syntax_diagnostics_ranges(vec![Range {
155            start: Position {
156                line: 1,
157                character: 21,
158            },
159            end: Position {
160                line: 1,
161                character: 23,
162            },
163        }]);
164
165        test_tree_structure!(
166            test_builder,
167            [
168                AllowEmpty<String> =!,
169            ]
170        );
171    }
172}