1use std::collections::HashMap;
6use std::io::ErrorKind;
7use std::path::Path;
8use std::sync::LazyLock;
9
10#[doc(hidden)]
11pub struct BuiltinFile {
12 pub name: &'static str,
13 pub content: &'static str,
14}
15inventory::collect!(BuiltinFile);
16
17#[doc(hidden)]
18pub use inventory::submit;
19
20#[macro_export]
25macro_rules! builtin_file {
26 ($name: literal) => {
27 $crate::util::fs::builtin_file!($name, include_str!($name));
28 };
29
30 ($name: literal, $content: expr) => {
31 $crate::util::fs::submit!($crate::util::fs::BuiltinFile {
32 name: $name,
33 content: $content,
34 });
35 };
36}
37pub use crate::builtin_file;
38
39static BUILTINS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
40 inventory::iter::<BuiltinFile>()
41 .map(|x| (x.name, x.content))
42 .collect()
43});
44
45pub fn read_to_string(path: &Path) -> std::io::Result<String> {
47 if let Ok(builtin) = path.strip_prefix("/__builtin__") {
48 Ok(BUILTINS
49 .get(builtin.to_str().ok_or(ErrorKind::NotFound)?)
50 .ok_or(ErrorKind::NotFound)?
51 .to_string())
52 } else {
53 std::fs::read_to_string(path)
54 }
55}