daipendency_extractor/
parsing.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use thiserror::Error;
use tree_sitter::{Language, LanguageError, Parser};

#[derive(Error, Debug)]
#[error(transparent)]
pub struct ParserError(#[from] LanguageError);

pub fn get_parser(parser_language: &Language) -> Result<Parser, ParserError> {
    let mut parser = Parser::new();
    parser.set_language(parser_language).map_err(ParserError)?;
    Ok(parser)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::ffi::c_void;

    // Minimal valid language struct matching tree-sitter's TSLanguage
    #[repr(C)]
    struct MinimalLanguage {
        version: u32,
        symbol_count: u32,
        symbol_metadata: &'static [u32],
        parse_actions: &'static [u16],
        lex_modes: &'static [u32],
        symbol_names: &'static [&'static str],
        field_count: u32,
        field_names: &'static [&'static str],
        field_map_slices: &'static [u8],
        field_map_entries: &'static [u16],
        parse_table: &'static [u16],
        lex_fn: Option<unsafe extern "C" fn(*mut c_void, u32, *mut c_void) -> bool>,
    }

    static MINIMAL_LANGUAGE: MinimalLanguage = MinimalLanguage {
        version: 14, // TREE_SITTER_LANGUAGE_VERSION
        symbol_count: 1,
        symbol_metadata: &[0],
        parse_actions: &[0],
        lex_modes: &[0],
        symbol_names: &["root"],
        field_count: 0,
        field_names: &[],
        field_map_slices: &[],
        field_map_entries: &[],
        parse_table: &[0],
        lex_fn: None,
    };

    #[test]
    fn get_parser_valid() {
        let language = unsafe { Language::from_raw(&MINIMAL_LANGUAGE as *const _ as *const _) };

        let result = get_parser(&language);

        assert!(result.is_ok());
    }
}