Impl per-target syntax mappings

This commit is contained in:
cyqsimon 2023-11-05 12:22:26 +08:00
parent 2c9bf229e1
commit 0c1b80faab
No known key found for this signature in database
GPG key ID: 1D8CE2F297390D65
10 changed files with 57 additions and 13 deletions

View file

@ -1,4 +1,9 @@
use std::{convert::Infallible, env, fs, path::Path, str::FromStr}; use std::{
convert::Infallible,
env, fs,
path::{Path, PathBuf},
str::FromStr,
};
use anyhow::{anyhow, bail}; use anyhow::{anyhow, bail};
use indexmap::IndexMap; use indexmap::IndexMap;
@ -181,19 +186,56 @@ impl MappingList {
} }
} }
/// Get the list of paths to all mapping definition files that should be
/// included for the current target platform.
fn get_def_paths() -> anyhow::Result<Vec<PathBuf>> {
let source_subdirs = [
"common",
#[cfg(target_family = "unix")]
"unix-family",
#[cfg(any(
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "macos"
))]
"bsd-family",
#[cfg(target_os = "linux")]
"linux",
#[cfg(target_os = "macos")]
"macos",
#[cfg(target_os = "windows")]
"windows",
];
let mut toml_paths = vec![];
for subdir in source_subdirs {
let wd = WalkDir::new(Path::new("src/syntax_mapping/builtins").join(subdir));
let paths = wd
.into_iter()
.filter_map_ok(|entry| {
let path = entry.path();
(path.is_file() && path.extension().map(|ext| ext == "toml").unwrap_or(false))
.then(|| path.to_owned())
})
.collect::<Result<Vec<_>, _>>()?;
toml_paths.extend(paths);
}
toml_paths.sort_by_key(|path| {
path.file_name()
.expect("file name should not terminate in ..")
.to_owned()
});
Ok(toml_paths)
}
fn read_all_mappings() -> anyhow::Result<MappingList> { fn read_all_mappings() -> anyhow::Result<MappingList> {
let mut all_mappings = vec![]; let mut all_mappings = vec![];
for entry in WalkDir::new("src/syntax_mapping/builtins") for path in get_def_paths()? {
.sort_by_file_name() let toml_string = fs::read_to_string(path)?;
.into_iter()
.map(|entry| entry.unwrap_or_else(|err| panic!("failed to visit a file: {err}")))
.filter(|entry| {
let path = entry.path();
path.is_file() && path.extension().map(|ext| ext == "toml").unwrap_or(false)
})
{
let toml_string = fs::read_to_string(entry.path())?;
let mappings = toml::from_str::<MappingDefModel>(&toml_string)?.into_mapping_list(); let mappings = toml::from_str::<MappingDefModel>(&toml_string)?.into_mapping_list();
all_mappings.extend(mappings.0); all_mappings.extend(mappings.0);
} }

View file

@ -13,8 +13,10 @@ What defines "a single application" here is deliberately vague, since the
file-splitting is purely for maintainability reasons. (Technically, we could file-splitting is purely for maintainability reasons. (Technically, we could
just as well use a single TOML file.) So just use common sense. just as well use a single TOML file.) So just use common sense.
At compile time, the build script will collect all the syntax mappings defined TOML files should reside in the corresponding subdirectory of the platform(s)
by the TOML files within this directory, and embed them into the binary. that they intend to target. At compile time, the build script will go through
each subdirectory that is applicable to the compilation target, collect the
syntax mappings defined by all TOML files, and embed them into the binary.
## File syntax ## File syntax