Skip to main content

dioxus_code/
language.rs

1//! Tree-sitter grammar selection.
2//!
3//! [`Language`] is a closed set of Arborium language slugs. Each named variant
4//! is gated by the same cargo feature as the corresponding grammar in
5//! `dioxus-code`, so the enum exposes the variants compiled into this build.
6
7macro_rules! define_languages {
8    (
9        $(
10            $(#[$attr:meta])*
11            $variant:ident => $slug:literal
12        ),* $(,)?
13    ) => {
14        /// Tree-sitter grammar identifier.
15        ///
16        /// Each variant maps to an Arborium language slug via
17        /// [`Language::slug`]. Variants are gated by the same `lang-*` cargo
18        /// features as the grammar lookup table, so each build exposes the
19        /// variants enabled for that build.
20        ///
21        /// ```rust
22        /// use dioxus_code::Language;
23        /// assert_eq!(Language::Rust.slug(), "rust");
24        /// assert_eq!(Language::from_slug("brainfuck"), None);
25        /// ```
26        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27        #[non_exhaustive]
28        pub enum Language {
29            $(
30                $(#[$attr])*
31                #[doc = concat!("Arborium slug `\"", $slug, "\"`.")]
32                $variant,
33            )*
34        }
35
36        impl Language {
37            /// Every variant compiled into this build, in declaration order.
38            ///
39            /// Variants whose grammars are gated behind cargo features only
40            /// appear here when the corresponding feature is enabled.
41            ///
42            /// ```rust
43            /// use dioxus_code::Language;
44            /// assert!(Language::ALL.contains(&Language::Rust));
45            /// ```
46            pub const ALL: &'static [Language] = &[
47                $(
48                    $(#[$attr])*
49                    Self::$variant,
50                )*
51            ];
52
53            /// Arborium slug for this language.
54            pub const fn slug(self) -> &'static str {
55                match self {
56                    $(
57                        $(#[$attr])*
58                        Self::$variant => $slug,
59                    )*
60                }
61            }
62
63            /// Parse an Arborium slug into a [`Language`].
64            ///
65            /// Returns `None` for unknown slugs and for slugs whose grammar
66            /// feature is disabled in this build.
67            pub fn from_slug(slug: &str) -> Option<Self> {
68                match slug {
69                    $(
70                        $(#[$attr])*
71                        $slug => Some(Self::$variant),
72                    )*
73                    _ => None,
74                }
75            }
76        }
77    };
78}
79
80impl Language {
81    /// Best-effort detection from a path, filename, shebang, or file contents.
82    ///
83    /// Wraps [`arborium::detect_language`] and maps the resulting slug into a
84    /// [`Language`] variant, returning `None` when detection fails or the
85    /// detected language's grammar feature is disabled in this build.
86    ///
87    /// Available with the `runtime` feature.
88    #[cfg(feature = "runtime")]
89    #[cfg_attr(docsrs, doc(cfg(feature = "runtime")))]
90    pub fn detect(input: &str) -> Option<Self> {
91        arborium::detect_language(input).and_then(Self::from_slug)
92    }
93}
94
95define_languages! {
96    Rust => "rust",
97    #[cfg(feature = "lang-ada")]
98    Ada => "ada",
99    #[cfg(feature = "lang-agda")]
100    Agda => "agda",
101    #[cfg(feature = "lang-asciidoc")]
102    Asciidoc => "asciidoc",
103    #[cfg(feature = "lang-asm")]
104    Asm => "asm",
105    #[cfg(feature = "lang-awk")]
106    Awk => "awk",
107    #[cfg(feature = "lang-bash")]
108    Bash => "bash",
109    #[cfg(feature = "lang-batch")]
110    Batch => "batch",
111    #[cfg(feature = "lang-c")]
112    C => "c",
113    #[cfg(feature = "lang-c-sharp")]
114    CSharp => "c-sharp",
115    #[cfg(feature = "lang-caddy")]
116    Caddy => "caddy",
117    #[cfg(feature = "lang-capnp")]
118    Capnp => "capnp",
119    #[cfg(feature = "lang-cedar")]
120    Cedar => "cedar",
121    #[cfg(feature = "lang-cedarschema")]
122    CedarSchema => "cedarschema",
123    #[cfg(feature = "lang-clojure")]
124    Clojure => "clojure",
125    #[cfg(feature = "lang-cmake")]
126    CMake => "cmake",
127    #[cfg(feature = "lang-cobol")]
128    Cobol => "cobol",
129    #[cfg(feature = "lang-commonlisp")]
130    CommonLisp => "commonlisp",
131    #[cfg(feature = "lang-cpp")]
132    Cpp => "cpp",
133    #[cfg(feature = "lang-css")]
134    Css => "css",
135    #[cfg(feature = "lang-d")]
136    D => "d",
137    #[cfg(feature = "lang-dart")]
138    Dart => "dart",
139    #[cfg(feature = "lang-devicetree")]
140    DeviceTree => "devicetree",
141    #[cfg(feature = "lang-diff")]
142    Diff => "diff",
143    #[cfg(feature = "lang-dockerfile")]
144    Dockerfile => "dockerfile",
145    #[cfg(feature = "lang-dot")]
146    Dot => "dot",
147    #[cfg(feature = "lang-elisp")]
148    Elisp => "elisp",
149    #[cfg(feature = "lang-elixir")]
150    Elixir => "elixir",
151    #[cfg(feature = "lang-elm")]
152    Elm => "elm",
153    #[cfg(feature = "lang-erlang")]
154    Erlang => "erlang",
155    #[cfg(feature = "lang-fish")]
156    Fish => "fish",
157    #[cfg(feature = "lang-fsharp")]
158    FSharp => "fsharp",
159    #[cfg(feature = "lang-gleam")]
160    Gleam => "gleam",
161    #[cfg(feature = "lang-glsl")]
162    Glsl => "glsl",
163    #[cfg(feature = "lang-go")]
164    Go => "go",
165    #[cfg(feature = "lang-graphql")]
166    GraphQL => "graphql",
167    #[cfg(feature = "lang-groovy")]
168    Groovy => "groovy",
169    #[cfg(feature = "lang-haskell")]
170    Haskell => "haskell",
171    #[cfg(feature = "lang-hcl")]
172    Hcl => "hcl",
173    #[cfg(feature = "lang-hlsl")]
174    Hlsl => "hlsl",
175    #[cfg(feature = "lang-html")]
176    Html => "html",
177    #[cfg(feature = "lang-idris")]
178    Idris => "idris",
179    #[cfg(feature = "lang-ini")]
180    Ini => "ini",
181    #[cfg(feature = "lang-java")]
182    Java => "java",
183    #[cfg(feature = "lang-javascript")]
184    JavaScript => "javascript",
185    #[cfg(feature = "lang-jinja2")]
186    Jinja2 => "jinja2",
187    #[cfg(feature = "lang-jq")]
188    Jq => "jq",
189    #[cfg(feature = "lang-json")]
190    Json => "json",
191    #[cfg(feature = "lang-julia")]
192    Julia => "julia",
193    #[cfg(feature = "lang-kotlin")]
194    Kotlin => "kotlin",
195    #[cfg(feature = "lang-lean")]
196    Lean => "lean",
197    #[cfg(feature = "lang-lua")]
198    Lua => "lua",
199    #[cfg(feature = "lang-markdown")]
200    Markdown => "markdown",
201    #[cfg(feature = "lang-matlab")]
202    Matlab => "matlab",
203    #[cfg(feature = "lang-meson")]
204    Meson => "meson",
205    #[cfg(feature = "lang-nginx")]
206    Nginx => "nginx",
207    #[cfg(feature = "lang-ninja")]
208    Ninja => "ninja",
209    #[cfg(feature = "lang-nix")]
210    Nix => "nix",
211    #[cfg(feature = "lang-objc")]
212    ObjectiveC => "objc",
213    #[cfg(feature = "lang-ocaml")]
214    OCaml => "ocaml",
215    #[cfg(feature = "lang-perl")]
216    Perl => "perl",
217    #[cfg(feature = "lang-php")]
218    Php => "php",
219    #[cfg(feature = "lang-postscript")]
220    PostScript => "postscript",
221    #[cfg(feature = "lang-powershell")]
222    PowerShell => "powershell",
223    #[cfg(feature = "lang-prolog")]
224    Prolog => "prolog",
225    #[cfg(feature = "lang-python")]
226    Python => "python",
227    #[cfg(feature = "lang-query")]
228    Query => "query",
229    #[cfg(feature = "lang-r")]
230    R => "r",
231    #[cfg(feature = "lang-rego")]
232    Rego => "rego",
233    #[cfg(feature = "lang-rescript")]
234    Rescript => "rescript",
235    #[cfg(feature = "lang-ron")]
236    Ron => "ron",
237    #[cfg(feature = "lang-ruby")]
238    Ruby => "ruby",
239    #[cfg(feature = "lang-scala")]
240    Scala => "scala",
241    #[cfg(feature = "lang-scheme")]
242    Scheme => "scheme",
243    #[cfg(feature = "lang-scss")]
244    Scss => "scss",
245    #[cfg(feature = "lang-solidity")]
246    Solidity => "solidity",
247    #[cfg(feature = "lang-sparql")]
248    Sparql => "sparql",
249    #[cfg(feature = "lang-sql")]
250    Sql => "sql",
251    #[cfg(feature = "lang-ssh-config")]
252    SshConfig => "ssh-config",
253    #[cfg(feature = "lang-starlark")]
254    Starlark => "starlark",
255    #[cfg(feature = "lang-styx")]
256    Styx => "styx",
257    #[cfg(feature = "lang-svelte")]
258    Svelte => "svelte",
259    #[cfg(feature = "lang-swift")]
260    Swift => "swift",
261    #[cfg(feature = "lang-textproto")]
262    Textproto => "textproto",
263    #[cfg(feature = "lang-thrift")]
264    Thrift => "thrift",
265    #[cfg(feature = "lang-tlaplus")]
266    TlaPlus => "tlaplus",
267    #[cfg(feature = "lang-toml")]
268    Toml => "toml",
269    #[cfg(feature = "lang-tsx")]
270    Tsx => "tsx",
271    #[cfg(feature = "lang-typescript")]
272    TypeScript => "typescript",
273    #[cfg(feature = "lang-typst")]
274    Typst => "typst",
275    #[cfg(feature = "lang-uiua")]
276    Uiua => "uiua",
277    #[cfg(feature = "lang-vb")]
278    VisualBasic => "vb",
279    #[cfg(feature = "lang-verilog")]
280    Verilog => "verilog",
281    #[cfg(feature = "lang-vhdl")]
282    Vhdl => "vhdl",
283    #[cfg(feature = "lang-vim")]
284    Vim => "vim",
285    #[cfg(feature = "lang-vue")]
286    Vue => "vue",
287    #[cfg(feature = "lang-wit")]
288    Wit => "wit",
289    #[cfg(feature = "lang-x86asm")]
290    X86Asm => "x86asm",
291    #[cfg(feature = "lang-xml")]
292    Xml => "xml",
293    #[cfg(feature = "lang-yaml")]
294    Yaml => "yaml",
295    #[cfg(feature = "lang-yuri")]
296    Yuri => "yuri",
297    #[cfg(feature = "lang-zig")]
298    Zig => "zig",
299    #[cfg(feature = "lang-zsh")]
300    Zsh => "zsh",
301}