Skip to content

Instantly share code, notes, and snippets.

@thomcc
Last active March 12, 2022 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomcc/6e2589c8304858dae9d4f32f953dace4 to your computer and use it in GitHub Desktop.
Save thomcc/6e2589c8304858dae9d4f32f953dace4 to your computer and use it in GitHub Desktop.
macro_rules! target_cfg {
($key:ident = $value:expr) => {{
const _: () = if !$crate::cfg::__internal::validate_cfg(stringify!($key)) {
panic!(concat!(
"bug: invalid use of `target_cfg!(",
stringify!($key),
" = ",
stringify!($value),
")`",
));
};
$crate::cfg::__internal::cfg_test(stringify!($key), Some($value))
}};
($key:ident) => {{
const _: () = if !$crate::cfg::__internal::validate_cfg(stringify!($key)) {
panic!(concat!(
"bug: invalid use of `target_cfg!(",
stringify!($key),
")`"
));
};
$crate::cfg::__internal::cfg_test(stringify!($key), None)
}};
}
#[doc(hidden)]
pub(crate) mod __internal {
#[track_caller]
pub(crate) fn cfg_test(cfg: &str, query: Option<&str>) -> bool {
assert!(
validate_cfg(cfg),
"should have already checked {:?}?",
(cfg, query),
);
let var_name = format!("CARGO_CFG_{}", cfg.to_ascii_uppercase());
let var_value = std::env::var(&var_name);
eprintln!(
"cfg test [from {:?}]: `{}={:?}`",
core::panic::Location::caller(),
var_name,
var_value,
);
match (query, var_value.ok().as_deref()) {
(None, Some(_)) => true,
// (None, Some(s)) => true,
(Some(""),) => false,
(Some(want), Some(have)) => want == have || have.split(",").any(|v| v == want),
}
}
pub(crate) const fn validate_cfg(s: &str) -> bool {
let s = s.as_bytes();
match s {
b"" => return false,
b"unix" => return true,
b"windows" => return true,
[b't', b'a', b'r', b'g', b'e', b't', b'_', rest @ ..] => valid_ident_bytes(rest),
_ => return false,
}
}
// tests something like `/^[_a-zA-Z][_a-zA-Z0-9]*$/`.
const fn valid_ident_bytes(s: &[u8]) -> bool {
if s.is_empty() || s[0].is_ascii_digit() {
return false;
}
let mut i = 0;
while i != s.len() {
let c = s[i];
let valid = c == b'_' || c.is_ascii_alphanumeric();
if !valid {
return false;
}
i += 1;
}
true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment