df_ls_syntax_analysis 0.3.0-rc.1

A language server for Dwarf Fortress RAW files
Documentation
use super::super::{Token, TryFromArgumentGroup};
use super::TokenDeserialize;
use df_ls_diagnostics::DiagnosticsInfo;

// Deserialize a token with following pattern: `[REF:Option<T>]`
crate::token_deserialize_unary_token!(Option<T>, T);

// ------------------------- Convert a group of arguments to Self -----------------------

impl<T> TryFromArgumentGroup for Option<T>
where
    T: TryFromArgumentGroup,
{
    fn try_from_argument_group(
        token: &mut Token,
        source: &str,
        diagnostics: &mut DiagnosticsInfo,
        add_diagnostics_on_err: bool,
    ) -> Result<Self, ()> {
        let arg_opt = token.get_current_arg_opt();
        if arg_opt.is_some() {
            match T::try_from_argument_group(token, source, diagnostics, add_diagnostics_on_err) {
                Ok(value) => Ok(Some(value)),
                Err(_) => Err(()),
            }
        } else {
            Ok(None)
        }
    }
}

// -------------------------Convert one argument to Self -----------------------
// TryFromArgument is not used, use TryFromArgumentGroup instead

// ---------------------------- TESTS --------------------------
#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_tree_structure;
    use crate::test_utils::SyntaxTestBuilder;
    use df_ls_diagnostics::{Position, Range};
    use df_ls_lexical_analysis::test_utils::LexerTestBuilder;

    #[test]
    fn test_option_string_correct() {
        let test_builder = SyntaxTestBuilder::from_lexer_test_builder(
            LexerTestBuilder::test_source(
                "header
                [REF:optional argument]
                [REF]",
            )
            .add_test_lexer_diagnostics_codes(vec![])
            .add_test_lexer_diagnostics_ranges(vec![]),
        )
        .add_test_syntax_diagnostics_codes(vec![])
        .add_test_syntax_diagnostics_ranges(vec![]);

        test_tree_structure!(
            test_builder,
            [
                Option<String> => Some("optional argument".to_owned()),
                Option<String> => None,
            ]
        );
    }

    #[test]
    fn test_option_string_to_many_args() {
        let test_builder = SyntaxTestBuilder::from_lexer_test_builder(
            LexerTestBuilder::test_source(
                "header
                [REF::]",
            )
            .add_test_lexer_diagnostics_codes(vec![])
            .add_test_lexer_diagnostics_ranges(vec![]),
        )
        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_type", "unchecked_code"])
        .add_test_syntax_diagnostics_ranges(vec![
            Range {
                start: Position {
                    line: 1,
                    character: 21,
                },
                end: Position {
                    line: 1,
                    character: 21,
                },
            },
            Range {
                start: Position {
                    line: 1,
                    character: 21,
                },
                end: Position {
                    line: 1,
                    character: 22,
                },
            },
        ]);

        test_tree_structure!(
            test_builder,
            [
                Option<String> =!,
            ]
        );
    }

    #[test]
    fn test_option_tuple_to_many_args() {
        let test_builder = SyntaxTestBuilder::from_lexer_test_builder(
            LexerTestBuilder::test_source(
                "header
                [REF:::]",
            )
            .add_test_lexer_diagnostics_codes(vec![])
            .add_test_lexer_diagnostics_ranges(vec![]),
        )
        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_type", "unchecked_code"])
        .add_test_syntax_diagnostics_ranges(vec![
            Range {
                start: Position {
                    line: 1,
                    character: 21,
                },
                end: Position {
                    line: 1,
                    character: 21,
                },
            },
            Range {
                start: Position {
                    line: 1,
                    character: 21,
                },
                end: Position {
                    line: 1,
                    character: 23,
                },
            },
        ]);

        test_tree_structure!(
            test_builder,
            [
                Option<(String, String)> =!,
            ]
        );
    }

    #[test]
    fn test_option_string_with_empty_arg() {
        let test_builder = SyntaxTestBuilder::from_lexer_test_builder(
            LexerTestBuilder::test_source(
                "header
                [REF:]",
            )
            .add_test_lexer_diagnostics_codes(vec![])
            .add_test_lexer_diagnostics_ranges(vec![]),
        )
        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_type"])
        .add_test_syntax_diagnostics_ranges(vec![Range {
            start: Position {
                line: 1,
                character: 21,
            },
            end: Position {
                line: 1,
                character: 21,
            },
        }]);

        test_tree_structure!(
            test_builder,
            [
                Option<String> =!,
            ]
        );
    }

    #[test]
    fn test_option_string_wrong_arg_type() {
        let test_builder = SyntaxTestBuilder::from_lexer_test_builder(
            LexerTestBuilder::test_source(
                "header
                [REF:56]",
            )
            .add_test_lexer_diagnostics_codes(vec![])
            .add_test_lexer_diagnostics_ranges(vec![]),
        )
        .add_test_syntax_diagnostics_codes(vec!["wrong_arg_type"])
        .add_test_syntax_diagnostics_ranges(vec![Range {
            start: Position {
                line: 1,
                character: 21,
            },
            end: Position {
                line: 1,
                character: 23,
            },
        }]);

        test_tree_structure!(
            test_builder,
            [
                Option<String> =!,
            ]
        );
    }
}