mirror of
https://github.com/sharkdp/bat.git
synced 2025-08-17 19:42:19 +02:00
Build script: replace string-based codegen with quote
-based codegen
This commit is contained in:
28
Cargo.lock
generated
28
Cargo.lock
generated
@@ -141,6 +141,9 @@ dependencies = [
|
|||||||
"path_abs",
|
"path_abs",
|
||||||
"plist",
|
"plist",
|
||||||
"predicates",
|
"predicates",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -149,6 +152,7 @@ dependencies = [
|
|||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"shell-words",
|
"shell-words",
|
||||||
|
"syn",
|
||||||
"syntect",
|
"syntect",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"terminal-colorsaurus",
|
"terminal-colorsaurus",
|
||||||
@@ -1163,10 +1167,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "prettyplease"
|
||||||
version = "1.0.92"
|
version = "0.2.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
@@ -1182,9 +1196,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.38"
|
version = "1.0.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -1440,9 +1454,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.95"
|
version = "2.0.104"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@@ -108,10 +108,14 @@ anyhow = "1.0.97"
|
|||||||
indexmap = { version = "2.8.0", features = ["serde"] }
|
indexmap = { version = "2.8.0", features = ["serde"] }
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
once_cell = "1.20"
|
once_cell = "1.20"
|
||||||
|
prettyplease = "0.2.35"
|
||||||
|
proc-macro2 = "1.0.95"
|
||||||
|
quote = "1.0.40"
|
||||||
regex = "1.10.6"
|
regex = "1.10.6"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_with = { version = "3.12.0", default-features = false, features = ["macros"] }
|
serde_with = { version = "3.12.0", default-features = false, features = ["macros"] }
|
||||||
|
syn = { version = "2.0.104", features = ["full"] }
|
||||||
toml = { version = "0.8.19", features = ["preserve_order"] }
|
toml = { version = "0.8.19", features = ["preserve_order"] }
|
||||||
walkdir = "2.5"
|
walkdir = "2.5"
|
||||||
|
|
||||||
|
@@ -9,6 +9,8 @@ use anyhow::{anyhow, bail};
|
|||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{quote, ToTokens, TokenStreamExt};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use serde_with::DeserializeFromStr;
|
use serde_with::DeserializeFromStr;
|
||||||
@@ -34,13 +36,14 @@ impl FromStr for MappingTarget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl MappingTarget {
|
impl ToTokens for MappingTarget {
|
||||||
fn codegen(&self) -> String {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
match self {
|
let t = match self {
|
||||||
Self::MapTo(syntax) => format!(r###"MappingTarget::MapTo(r#"{syntax}"#)"###),
|
Self::MapTo(syntax) => quote! { MappingTarget::MapTo(#syntax) },
|
||||||
Self::MapToUnknown => "MappingTarget::MapToUnknown".into(),
|
Self::MapToUnknown => quote! { MappingTarget::MapToUnknown },
|
||||||
Self::MapExtensionToUnknown => "MappingTarget::MapExtensionToUnknown".into(),
|
Self::MapExtensionToUnknown => quote! { MappingTarget::MapExtensionToUnknown },
|
||||||
}
|
};
|
||||||
|
tokens.append_all(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,22 +119,17 @@ impl FromStr for Matcher {
|
|||||||
Ok(Self(non_empty_segments))
|
Ok(Self(non_empty_segments))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Matcher {
|
impl ToTokens for Matcher {
|
||||||
fn codegen(&self) -> String {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
match self.0.len() {
|
let t = match self.0.as_slice() {
|
||||||
0 => unreachable!("0-length matcher should never be created"),
|
[] => unreachable!("0-length matcher should never be created"),
|
||||||
// if-let guard would be ideal here
|
[MatcherSegment::Text(text)] => {
|
||||||
// see: https://github.com/rust-lang/rust/issues/51114
|
quote! { Lazy::new(|| Some(build_matcher_fixed(#text)))}
|
||||||
1 if self.0[0].is_text() => {
|
|
||||||
let s = self.0[0].text().unwrap();
|
|
||||||
format!(r###"Lazy::new(|| Some(build_matcher_fixed(r#"{s}"#)))"###)
|
|
||||||
}
|
}
|
||||||
// parser logic ensures that this case can only happen when there are dynamic segments
|
// parser logic ensures that this case can only happen when there are dynamic segments
|
||||||
_ => {
|
segs @ [_, ..] => quote! { Lazy::new(|| build_matcher_dynamic(&[ #(#segs),* ]))},
|
||||||
let segs = self.0.iter().map(MatcherSegment::codegen).join(", ");
|
};
|
||||||
format!(r###"Lazy::new(|| build_matcher_dynamic(&[{segs}]))"###)
|
tokens.append_all(t);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,6 +141,15 @@ enum MatcherSegment {
|
|||||||
Text(String),
|
Text(String),
|
||||||
Env(String),
|
Env(String),
|
||||||
}
|
}
|
||||||
|
impl ToTokens for MatcherSegment {
|
||||||
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
let t = match self {
|
||||||
|
Self::Text(text) => quote! { MatcherSegment::Text(#text)},
|
||||||
|
Self::Env(env) => quote! {MatcherSegment::Env(#env)},
|
||||||
|
};
|
||||||
|
tokens.append_all(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl MatcherSegment {
|
impl MatcherSegment {
|
||||||
fn is_text(&self) -> bool {
|
fn is_text(&self) -> bool {
|
||||||
@@ -163,12 +170,6 @@ impl MatcherSegment {
|
|||||||
Self::Env(t) => Some(t),
|
Self::Env(t) => Some(t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn codegen(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Self::Text(s) => format!(r###"MatcherSegment::Text(r#"{s}"#)"###),
|
|
||||||
Self::Env(s) => format!(r###"MatcherSegment::Env(r#"{s}"#)"###),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct that models a single .toml file in /src/syntax_mapping/builtins/.
|
/// A struct that models a single .toml file in /src/syntax_mapping/builtins/.
|
||||||
@@ -194,22 +195,19 @@ impl MappingDefModel {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct MappingList(Vec<(Matcher, MappingTarget)>);
|
struct MappingList(Vec<(Matcher, MappingTarget)>);
|
||||||
impl MappingList {
|
impl ToTokens for MappingList {
|
||||||
fn codegen(&self) -> String {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
let array_items: Vec<_> = self
|
let len = self.0.len();
|
||||||
|
let array_items = self
|
||||||
.0
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(matcher, target)| {
|
.map(|(matcher, target)| quote! { (#matcher, #target) });
|
||||||
format!("({m}, {t})", m = matcher.codegen(), t = target.codegen())
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let len = array_items.len();
|
|
||||||
|
|
||||||
format!(
|
let t = quote! {
|
||||||
"/// Generated by build script from /src/syntax_mapping/builtins/.\n\
|
/// Generated by build script from /src/syntax_mapping/builtins/.
|
||||||
pub(crate) static BUILTIN_MAPPINGS: [(Lazy<Option<GlobMatcher>>, MappingTarget); {len}] = [\n{items}\n];",
|
pub(crate) static BUILTIN_MAPPINGS: [(Lazy<Option<GlobMatcher>>, MappingTarget); #len] = [#(#array_items),*];
|
||||||
items = array_items.join(",\n")
|
};
|
||||||
)
|
tokens.append_all(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,11 +288,13 @@ pub fn build_static_mappings() -> anyhow::Result<()> {
|
|||||||
println!("cargo:rerun-if-changed=src/syntax_mapping/builtins/");
|
println!("cargo:rerun-if-changed=src/syntax_mapping/builtins/");
|
||||||
|
|
||||||
let mappings = read_all_mappings()?;
|
let mappings = read_all_mappings()?;
|
||||||
|
let rs_src = syn::parse_file(&mappings.to_token_stream().to_string())?;
|
||||||
|
let rs_src_pretty = prettyplease::unparse(&rs_src);
|
||||||
|
|
||||||
let codegen_path = Path::new(&env::var_os("OUT_DIR").ok_or(anyhow!("OUT_DIR is unset"))?)
|
let codegen_path = Path::new(&env::var_os("OUT_DIR").ok_or(anyhow!("OUT_DIR is unset"))?)
|
||||||
.join("codegen_static_syntax_mappings.rs");
|
.join("codegen_static_syntax_mappings.rs");
|
||||||
|
|
||||||
fs::write(codegen_path, mappings.codegen())?;
|
fs::write(codegen_path, rs_src_pretty)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user