pub use regex::{Captures, Regex};
use rustc_hash::FxHashMap;
use schematic::{MergeError, MergeResult, PartialConfig};
use std::collections::BTreeMap;
use std::hash::Hash;
use std::sync::LazyLock;
macro_rules! pattern {
($name:ident, $regex:literal) => {
pub static $name: LazyLock<regex::Regex> = LazyLock::new(|| Regex::new($regex).unwrap());
};
}
pattern!(ENV_VAR_DISTINCT, "^\\$([A-Z0-9_]+)$"); pattern!(ENV_VAR_GLOB_DISTINCT, "^\\$([A-Z0-9_*]+)$");
pattern!(TOKEN_FUNC, "@([a-z]+)\\(([0-9A-Za-z_-]+)\\)");
pattern!(TOKEN_FUNC_DISTINCT, "^@([a-z]+)\\(([0-9A-Za-z_-]+)\\)$");
pattern!(
TOKEN_VAR,
"\\$(arch|language|osFamily|os|projectAliases|projectAlias|projectChannel|projectId|projectLayer|projectName|projectTitle|projectOwner|projectRoot|projectSource|projectStack|project|target|taskId|taskToolchains|taskToolchain|taskType|task|timestamp|datetime|date|time|vcsBranch|vcsRepository|vcsRevision|workingDir|workspaceRoot)"
);
pattern!(
TOKEN_VAR_DISTINCT,
"^\\$(arch|language|osFamily|os|projectAliases|projectAlias|projectChannel|projectId|projectLayer|projectName|projectTitle|projectOwner|projectRoot|projectSource|projectStack|project|target|taskId|taskToolchains|taskToolchain|taskType|task|timestamp|datetime|date|time|vcsBranch|vcsRepository|vcsRevision|workingDir|workspaceRoot)$"
);
pub fn merge_iter<I, V, C>(mut prev: I, next: I, _: &C) -> MergeResult<I>
where
I: Extend<V> + IntoIterator<Item = V>,
{
prev.extend(next);
Ok(Some(prev))
}
pub fn merge_plugin_partials<K, V>(
mut prev: FxHashMap<K, V>,
next: FxHashMap<K, V>,
context: &V::Context,
) -> MergeResult<FxHashMap<K, V>>
where
K: Eq + Hash,
V: PartialConfig,
{
for (key, value) in next {
match prev.get_mut(&key) {
Some(existing) => {
existing.merge(context, value).map_err(MergeError::new)?;
}
None => {
prev.insert(key, value);
}
}
}
Ok(Some(prev))
}
pub fn merge_tasks_partials<K, V>(
mut prev: BTreeMap<K, V>,
next: BTreeMap<K, V>,
context: &V::Context,
) -> MergeResult<BTreeMap<K, V>>
where
K: Eq + Hash + Ord,
V: PartialConfig,
{
for (key, value) in next {
match prev.get_mut(&key) {
Some(existing) => {
existing.merge(context, value).map_err(MergeError::new)?;
}
None => {
prev.insert(key, value);
}
}
}
Ok(Some(prev))
}