Skip to main content

lazy_static_include/
macro_include_array.rs

1#[cfg(debug_assertions)]
2/// Includes a file containing a rust array.
3///
4/// The file is located relative to the directory containing the manifest of your package.
5#[macro_export]
6macro_rules! lazy_static_include_array {
7    ( @i [$t:ident; $s:expr], $path:expr ) => {
8        {
9            let path = $crate::manifest_dir_macros::not_directory_path!($path);
10
11            let text = ::std::fs::read_to_string(path).unwrap();
12
13            let s = text.trim();
14
15            let mut result = [0 as $t; $s];
16
17            if let Ok($crate::syn::Expr::Array(array)) = $crate::syn::parse_str(s) {
18                for (i, l) in array.elems.into_iter().enumerate() {
19                    if i >= $s {
20                        panic!("incorrect length, bigger than {}, file: {}", $s, path);
21                    }
22
23                    let mut neg = false;
24
25                    let exp = match l {
26                        $crate::syn::Expr::Lit(exp) => exp,
27                        $crate::syn::Expr::Unary(exp) => {
28                            neg = true;
29
30                            match exp.expr.as_ref() {
31                                $crate::syn::Expr::Lit(exp) => exp.clone(),
32                                _ => {
33                                    panic!("incorrect element type, index = {}, file: {}", i, path);
34                                }
35                            }
36                        }
37                        _ => {
38                            panic!("incorrect element type, index = {}, file: {}", i, path);
39                        }
40                    };
41
42                    let accept_suffix = stringify!($t);
43
44                    match exp.lit {
45                        $crate::syn::Lit::Int(n) => {
46                            let suffix = n.suffix();
47
48                            if !suffix.is_empty() && suffix != accept_suffix {
49                                panic!("incorrect element type, index = {}, file: {}", i, path);
50                            }
51
52                            let n: $t = n.base10_parse().unwrap();
53
54                            result[i] = if neg {
55                                -n
56                            } else {
57                                n
58                            };
59                        }
60                        _ => {
61                            panic!("incorrect element type, index = {}, file: {}", i, path);
62                        }
63                    }
64                }
65
66                result
67            } else {
68                panic!("incorrect array, file: {}", path);
69            }
70        }
71    };
72    ( @u [$t:ident; $s:expr], $path:expr ) => {
73        {
74            let path = $crate::manifest_dir_macros::not_directory_path!($path);
75
76            let text = ::std::fs::read_to_string(path).unwrap();
77
78            let s = text.trim();
79
80            let mut result = [0 as $t; $s];
81
82            if let Ok($crate::syn::Expr::Array(array)) = $crate::syn::parse_str(s) {
83                for (i, l) in array.elems.into_iter().enumerate() {
84                    if i >= $s {
85                        panic!("incorrect length, bigger than {}, file: {}", $s, path);
86                    }
87
88                    let exp = match l {
89                        $crate::syn::Expr::Lit(exp) => exp,
90                        _ => {
91                            panic!("incorrect element type, index = {}, file: {}", i, path);
92                        }
93                    };
94
95                    let accept_suffix = stringify!($t);
96
97                    match exp.lit {
98                        $crate::syn::Lit::Int(n) => {
99                            let suffix = n.suffix();
100
101                            if !suffix.is_empty() && suffix != accept_suffix {
102                                panic!("incorrect element type, index = {}, file: {}", i, path);
103                            }
104
105                            result[i] = n.base10_parse().unwrap();
106                        }
107                        _ => {
108                            panic!("incorrect element type, index = {}, file: {}", i, path);
109                        }
110                    }
111                }
112
113                result
114            } else {
115                panic!("incorrect array, file: {}", path);
116            }
117        }
118    };
119    ( @f [$t:ident; $s:expr], $path:expr ) => {
120        {
121            let path = $crate::manifest_dir_macros::not_directory_path!($path);
122
123            let text = ::std::fs::read_to_string(path).unwrap();
124
125            let s = text.trim();
126
127            let mut result = [0 as $t; $s];
128
129            if let Ok($crate::syn::Expr::Array(array)) = $crate::syn::parse_str(s) {
130                for (i, l) in array.elems.into_iter().enumerate() {
131                    if i >= $s {
132                        panic!("incorrect length, bigger than {}, file: {}", $s, path);
133                    }
134
135                    let mut neg = false;
136
137                    let exp = match l {
138                        $crate::syn::Expr::Lit(exp) => exp,
139                        $crate::syn::Expr::Unary(exp) => {
140                            neg = true;
141
142                            match exp.expr.as_ref() {
143                                $crate::syn::Expr::Lit(exp) => exp.clone(),
144                                _ => {
145                                    panic!("incorrect element type, index = {}, file: {}", i, path);
146                                }
147                            }
148                        }
149                        _ => {
150                            panic!("incorrect element type, index = {}, file: {}", i, path);
151                        }
152                    };
153
154                    let accept_suffix = stringify!($t);
155
156                    match exp.lit {
157                        $crate::syn::Lit::Float(f) => {
158                            let suffix = f.suffix();
159
160                            if !suffix.is_empty() && suffix != accept_suffix {
161                                panic!("incorrect element type, index = {}, file: {}", i, path);
162                            }
163
164                            let f: $t = f.base10_parse().unwrap();
165
166                            result[i] = if neg {
167                                -f
168                            } else {
169                                f
170                            };
171                        }
172                        $crate::syn::Lit::Int(n) => {
173                            let suffix = n.suffix();
174
175                            if suffix != accept_suffix {
176                                panic!("incorrect element type, index = {}, file: {}", i, path);
177                            }
178
179                            let n: $t = n.base10_parse().unwrap();
180
181                            result[i] = if neg {
182                                -n
183                            } else {
184                                n
185                            };
186                        }
187                        _ => {
188                            panic!("incorrect element type, index = {}, file: {}", i, path);
189                        }
190                    }
191                }
192
193                result
194            } else {
195                panic!("incorrect array, file: {}", path);
196            }
197        }
198    };
199    ( @c [$t:ident; $s:expr], $path:expr ) => {
200        {
201            let path = $crate::manifest_dir_macros::not_directory_path!($path);
202
203            let text = ::std::fs::read_to_string(path).unwrap();
204
205            let s = text.trim();
206
207            let mut result = ['\0'; $s];
208
209            if let Ok($crate::syn::Expr::Array(array)) = $crate::syn::parse_str(s) {
210                for (i, l) in array.elems.into_iter().enumerate() {
211                    if i >= $s {
212                        panic!("incorrect length, bigger than {}, file: {}", $s, path);
213                    }
214
215                    if let $crate::syn::Expr::Lit(exp) = l {
216                        match exp.lit {
217                            $crate::syn::Lit::Char(c) => {
218                                result[i] = c.value();
219                            }
220                            _ => {
221                                panic!("incorrect element type, index = {}, file: {}", i, path);
222                            }
223                        }
224                    } else {
225                        panic!("incorrect element type, index = {}, file: {}", i, path);
226                    }
227                }
228
229                result
230            } else {
231                panic!("incorrect array, file: {}", path);
232            }
233        }
234    };
235    ( @b [$t:ident; $s:expr], $path:expr ) => {
236        {
237            let path = $crate::manifest_dir_macros::not_directory_path!($path);
238
239            let text = ::std::fs::read_to_string(path).unwrap();
240
241            let s = text.trim();
242
243            let mut result = [false; $s];
244
245            if let Ok($crate::syn::Expr::Array(array)) = $crate::syn::parse_str(s) {
246                for (i, l) in array.elems.into_iter().enumerate() {
247                    if i >= $s {
248                        panic!("incorrect length, bigger than {}, file: {}", $s, path);
249                    }
250
251                    if let $crate::syn::Expr::Lit(exp) = l {
252                        match exp.lit {
253                            $crate::syn::Lit::Bool(b) => {
254                                result[i] = b.value;
255                            }
256                            _ => {
257                                panic!("incorrect element type, index = {}, file: {}", i, path);
258                            }
259                        }
260                    } else {
261                        panic!("incorrect element type, index = {}, file: {}", i, path);
262                    }
263                }
264
265                result
266            } else {
267                panic!("incorrect array, file: {}", path);
268            }
269        }
270    };
271    ( @s [$s:expr], $path:expr ) => {
272        {
273            let path = $crate::manifest_dir_macros::not_directory_path!($path);
274
275            let text = ::std::fs::read_to_string(path).unwrap();
276
277            let s = text.trim();
278
279            let mut result: [&'static str; $s] = [""; $s];
280
281            if let Ok($crate::syn::Expr::Array(array)) = $crate::syn::parse_str(s) {
282                for (i, l) in array.elems.into_iter().enumerate() {
283                    if i >= $s {
284                        panic!("incorrect length, bigger than {}, file: {}", $s, path);
285                    }
286
287                    if let $crate::syn::Expr::Lit(exp) = l {
288                        match exp.lit {
289                            $crate::syn::Lit::Str(s) => {
290                                // Leak each string to get a `&'static str` reference, because the data needs to live as long as the program anyway.
291                                result[i] = s.value().leak();
292                            }
293                            _ => {
294                                panic!("incorrect element type, index = {}, file: {}", i, path);
295                            }
296                        }
297                    } else {
298                        panic!("incorrect element type, index = {}, file: {}", i, path);
299                    }
300                }
301
302                result
303            } else {
304                panic!("incorrect array, file: {}", path);
305            }
306        }
307    };
308    ( @type [isize; $s:expr], $path:expr ) => {
309        $crate::lazy_static_include_array!(@i [isize; $s], $path)
310    };
311    ( @type [i8; $s:expr], $path:expr ) => {
312        $crate::lazy_static_include_array!(@i [i8; $s], $path)
313    };
314    ( @type [i16; $s:expr], $path:expr ) => {
315        $crate::lazy_static_include_array!(@i [i16; $s], $path)
316    };
317    ( @type [i32; $s:expr], $path:expr ) => {
318        $crate::lazy_static_include_array!(@i [i32; $s], $path)
319    };
320    ( @type [i64; $s:expr], $path:expr ) => {
321        $crate::lazy_static_include_array!(@i [i64; $s], $path)
322    };
323    ( @type [i128; $s:expr], $path:expr ) => {
324        $crate::lazy_static_include_array!(@i [i128; $s], $path)
325    };
326    ( @type [usize; $s:expr], $path:expr ) => {
327        $crate::lazy_static_include_array!(@u [usize; $s], $path)
328    };
329    ( @type [u8; $s:expr], $path:expr ) => {
330        $crate::lazy_static_include_array!(@u [u8; $s], $path)
331    };
332    ( @type [u16; $s:expr], $path:expr ) => {
333        $crate::lazy_static_include_array!(@u [u16; $s], $path)
334    };
335    ( @type [u32; $s:expr], $path:expr ) => {
336        $crate::lazy_static_include_array!(@u [u32; $s], $path)
337    };
338    ( @type [u64; $s:expr], $path:expr ) => {
339        $crate::lazy_static_include_array!(@u [u64; $s], $path)
340    };
341    ( @type [u128; $s:expr], $path:expr ) => {
342        $crate::lazy_static_include_array!(@u [u128; $s], $path)
343    };
344    ( @type [f32; $s:expr], $path:expr ) => {
345        $crate::lazy_static_include_array!(@f [f32; $s], $path)
346    };
347    ( @type [f64; $s:expr], $path:expr ) => {
348        $crate::lazy_static_include_array!(@f [f64; $s], $path)
349    };
350    ( @type [char; $s:expr], $path:expr ) => {
351        $crate::lazy_static_include_array!(@c [char; $s], $path)
352    };
353    ( @type [bool; $s:expr], $path:expr ) => {
354        $crate::lazy_static_include_array!(@b [bool; $s], $path)
355    };
356    ( @type [&'static str; $s:expr], $path:expr ) => {
357        $crate::lazy_static_include_array!(@s [$s], $path)
358    };
359    ( @unit $(#[$attr: meta])* $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr ) => {
360        $(#[$attr])*
361        static $name: ::std::sync::LazyLock<[$(& $lt)? $t; $s]> = ::std::sync::LazyLock::new(|| $crate::lazy_static_include_array!(@type [$(& $lt)? $t; $s], $path));
362    };
363    ( @unit $(#[$attr: meta])* pub$(($($v:tt)+))? $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr ) => {
364        $(#[$attr])*
365        pub$(($($v)+))? static $name: ::std::sync::LazyLock<[$(& $lt)? $t; $s]> = ::std::sync::LazyLock::new(|| $crate::lazy_static_include_array!(@type [$(& $lt)? $t; $s], $path));
366    };
367    ( $($(#[$attr: meta])* $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr),* $(,)* ) => {
368        $(
369            $crate::lazy_static_include_array! {
370                @unit
371                $(#[$attr])*
372                $name: [$(& $lt)? $t; $s] => $path
373            }
374        )*
375    };
376    ( $($(#[$attr: meta])* pub$(($($v:tt)+))? $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr),* $(,)* ) => {
377        $(
378            $crate::lazy_static_include_array! {
379                @unit
380                $(#[$attr])*
381                pub$(($($v)+))? $name: [$(& $lt)? $t; $s] => $path
382            }
383        )*
384    };
385}
386
387#[cfg(not(debug_assertions))]
388/// Includes a file containing a rust array.
389///
390/// The file is located relative to the directory containing the manifest of your package.
391#[macro_export]
392macro_rules! lazy_static_include_array {
393    ( @unit $(#[$attr: meta])* $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr ) => {
394        $(#[$attr])*
395        static $name: ::std::sync::LazyLock<[$(& $lt)? $t; $s]> = ::std::sync::LazyLock::new(|| include!($crate::manifest_dir_macros::path!($path)));
396    };
397    ( @unit $(#[$attr: meta])* pub$(($($v:tt)+))? $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr ) => {
398        $(#[$attr])*
399        pub$(($($v)+))? static $name: ::std::sync::LazyLock<[$(& $lt)? $t; $s]> = ::std::sync::LazyLock::new(|| include!($crate::manifest_dir_macros::path!($path)));
400    };
401    ( $($(#[$attr: meta])* $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr),* $(,)* ) => {
402        $(
403            $crate::lazy_static_include_array! {
404                @unit
405                $(#[$attr])*
406                $name: [$(& $lt)? $t; $s] => $path
407            }
408        )*
409    };
410    ( $($(#[$attr: meta])* pub$(($($v:tt)+))? $name:ident: [$(& $lt:lifetime)? $t:ident; $s:expr] => $path:expr),* $(,)* ) => {
411        $(
412            $crate::lazy_static_include_array! {
413                @unit
414                $(#[$attr])*
415                pub$(($($v)+))? $name: [$(& $lt)? $t; $s] => $path
416            }
417        )*
418    };
419}