github_languages/
macros.rs1#[derive(Debug, Clone, PartialEq)]
2pub struct LanguageInfo {
3 pub name: &'static str,
4 pub r#type: &'static str,
5 pub color: &'static str,
6 pub extensions: &'static [&'static str],
7 pub aliases: &'static [&'static str],
8 pub tm_scope: &'static str,
9 pub ace_mode: &'static str,
10 pub language_id: u64,
11 pub codemirror_mode: Option<&'static str>,
12 pub codemirror_mime_type: Option<&'static str>,
13 pub wrap: Option<bool>,
14 pub filenames: &'static [&'static str],
15 pub group: Option<&'static str>,
16 pub interpreters: &'static [&'static str],
17 pub fs_name: Option<&'static str>,
18 pub searchable: Option<bool>,
19}
20
21#[macro_export]
22macro_rules! define_languages {
23 (
24 $(
25 $struct_name:ident => {
26 name: $name:literal,
27 r#type: $lang_type:literal,
28 color: $color:literal,
29 extensions: [ $( $ext:literal ),* $( , )? ],
30 aliases: [ $( $alias:literal ),* $( , )? ],
31 tm_scope: $tm_scope:literal,
32 ace_mode: $ace_mode:literal,
33 language_id: $id:literal,
34 $( codemirror_mode: $cm_mode:literal, )?
35 $( codemirror_mime_type: $cm_mime:literal, )?
36 $( wrap: $wrap:literal, )?
37 filenames: [ $( $filename:literal ),* $( , )? ],
38 $( group: $group:literal, )?
39 interpreters: [ $( $interp:literal ),* $( , )? ],
40 $( fs_name: $fs_name:literal, )?
41 $( searchable: $searchable:literal, )?
42 }
43 ),*
44 $( , )?
45 ) => {
46 use $crate::macros::LanguageInfo;
47 use once_cell::sync::Lazy;
48
49 $(
51 pub struct $struct_name;
52
53 impl $struct_name {
54 pub fn info() -> LanguageInfo {
55 LanguageInfo {
56 name: $name,
57 r#type: $lang_type,
58 color: $color,
59 extensions: &[ $( $ext ),* ],
60 aliases: &[ $( $alias ),* ],
61 tm_scope: $tm_scope,
62 ace_mode: $ace_mode,
63 language_id: $id,
64 codemirror_mode: None $(.or(Some($cm_mode)))?,
65 codemirror_mime_type: None $(.or(Some($cm_mime)))?,
66 wrap: None $(.or(Some($wrap)))?,
67 filenames: &[ $( $filename ),* ],
68 group: None $(.or(Some($group)))?,
69 interpreters: &[ $( $interp ),* ],
70 fs_name: None $(.or(Some($fs_name)))?,
71 searchable: None $(.or(Some($searchable)))?,
72 }
73 }
74 }
75 )*
76
77 pub struct Languages;
79
80 impl Languages {
81 pub fn get_by_name(&self, name: &str) -> Option<LanguageInfo> {
82 BY_NAME.get(name).map(|f| f())
83 }
84
85 pub fn get_by_id(&self, id: u64) -> Option<LanguageInfo> {
86 BY_ID.get(&id).map(|f| f())
87 }
88
89 pub fn get_by_extension(&self, ext: &str) -> Vec<LanguageInfo> {
90 BY_EXTENSION
91 .get(ext)
92 .map(|funcs| funcs.iter().map(|f| f()).collect())
93 .unwrap_or_default()
94 }
95
96 pub fn get_by_alias(&self, alias: &str) -> Vec<LanguageInfo> {
97 ALL_LANGUAGES.iter().filter(|lang| lang.aliases.contains(&alias)).cloned().collect()
98 }
99
100 pub fn get_by_filename(&self, filename: &str) -> Vec<LanguageInfo> {
101 ALL_LANGUAGES.iter().filter(|lang| lang.filenames.contains(&filename)).cloned().collect()
102 }
103
104 pub fn get_by_interpreter(&self, interpreter: &str) -> Vec<LanguageInfo> {
105 ALL_LANGUAGES.iter().filter(|lang| lang.interpreters.contains(&interpreter)).cloned().collect()
106 }
107
108 pub fn get_by_type(&self, r#type: &str) -> Vec<LanguageInfo> {
109 ALL_LANGUAGES.iter().filter(|lang| lang.r#type == r#type).cloned().collect()
110 }
111
112 pub fn all_languages(&self) -> &[LanguageInfo] {
113 &ALL_LANGUAGES
114 }
115 }
116
117 static ALL_LANGUAGES: Lazy<Vec<LanguageInfo>> = Lazy::new(|| vec![
119 $( $struct_name::info() ),*
120 ]);
121
122 static BY_NAME: phf::Map<&'static str, fn() -> LanguageInfo> = phf_map! {
123 $( $name => $struct_name::info ),*
124 };
125
126 static BY_ID: phf::Map<u64, fn() -> LanguageInfo> = phf_map! {
127 $( $id => $struct_name::info ),*
128 };
129
130 pub fn get_languages() -> Languages {
131 Languages
132 }
133
134 pub static LANGUAGES: Lazy<Languages> = Lazy::new(|| Languages);
135 };
136}