Skip to main content

panproto_grammars/
lib.rs

1#![allow(unsafe_code)]
2//! Pre-compiled tree-sitter grammars for panproto.
3//!
4//! This crate bundles up to 248 tree-sitter grammars, compiled from vendored C sources.
5//! Each grammar is gated behind a `lang-{name}` feature flag. Group features like
6//! `group-core`, `group-web`, `group-all` etc. enable sets of languages at once.
7//!
8//! The default feature is `group-core` (GitHub's top 10 languages + Rust).
9
10#[allow(
11    clippy::vec_init_then_push,
12    clippy::match_same_arms,
13    clippy::must_use_candidate,
14    clippy::redundant_pub_crate,
15    unreachable_pub
16)]
17mod generated {
18    include!(concat!(env!("OUT_DIR"), "/grammar_table.rs"));
19}
20use generated::{enabled_grammars, ext_to_lang};
21
22/// A compiled tree-sitter grammar with its metadata.
23pub struct Grammar {
24    /// Protocol name (e.g. `"python"`, `"typescript"`).
25    pub name: &'static str,
26    /// File extensions this grammar handles (e.g. `["py", "pyi"]`).
27    pub extensions: &'static [&'static str],
28    /// The tree-sitter `Language` object for parsing.
29    pub language: tree_sitter::Language,
30    /// Raw `node-types.json` bytes for theory extraction.
31    pub node_types: &'static [u8],
32}
33
34/// Return all grammars enabled by feature flags.
35///
36/// Each grammar provides a `Language` for parsing and `node_types` JSON for
37/// theory extraction. The returned list is sorted by grammar name.
38#[must_use]
39pub fn grammars() -> Vec<Grammar> {
40    enabled_grammars()
41        .into_iter()
42        .map(|e| {
43            let language = unsafe {
44                // SAFETY: `tree_sitter_{name}()` is an extern "C" function that returns
45                // a valid `TSLanguage*` pointer from the compiled C grammar. We cast the
46                // raw pointer back to the correct function pointer type. This is the
47                // standard tree-sitter FFI pattern used by every grammar crate.
48                let f: unsafe extern "C" fn() -> *const () = std::mem::transmute(e.language_fn_ptr);
49                tree_sitter_language::LanguageFn::from_raw(f).into()
50            };
51            Grammar {
52                name: e.name,
53                extensions: e.extensions,
54                language,
55                node_types: e.node_types,
56            }
57        })
58        .collect()
59}
60
61/// Check if a specific grammar is available (enabled by feature flags).
62#[must_use]
63pub fn has_grammar(name: &str) -> bool {
64    enabled_grammars().iter().any(|e| e.name == name)
65}
66
67/// Map a file extension to its grammar name.
68///
69/// Returns `None` if the extension is not recognized among enabled grammars.
70#[must_use]
71pub fn extension_to_language(ext: &str) -> Option<&'static str> {
72    ext_to_lang(ext)
73}
74
75/// Return the number of enabled grammars.
76#[must_use]
77pub fn grammar_count() -> usize {
78    enabled_grammars().len()
79}