tuwunel_core/info/
rustc.rs1use std::{
7 collections::BTreeMap,
8 mem::replace,
9 sync::{Mutex, OnceLock},
10};
11
12tuwunel_macros::rustc_version! {}
14
15pub static FLAGS: Mutex<BTreeMap<&str, &[&str]>> = Mutex::new(BTreeMap::new());
20
21static FEATURES: OnceLock<Vec<&'static str>> = OnceLock::new();
24
25pub fn features() -> &'static Vec<&'static str> { FEATURES.get_or_init(init_features) }
27
28#[inline]
30#[must_use]
31pub fn version() -> Option<&'static str> {
32 RUSTC_VERSION
33 .len()
34 .gt(&0)
35 .then_some(RUSTC_VERSION)
36}
37
38fn init_features() -> Vec<&'static str> {
39 let mut features = Vec::new();
40 FLAGS
41 .lock()
42 .expect("locked")
43 .iter()
44 .for_each(|(_, flags)| append_features(&mut features, flags));
45
46 features.sort_unstable();
47 features.dedup();
48 features
49}
50
51fn append_features(features: &mut Vec<&'static str>, flags: &[&'static str]) {
52 let mut next_is_cfg = false;
53 for flag in flags {
54 let is_cfg = *flag == "--cfg";
55 let is_feature = flag.starts_with("feature=");
56 if replace(&mut next_is_cfg, is_cfg)
57 && is_feature
58 && let Some(feature) = flag
59 .split_once('=')
60 .map(|(_, feature)| feature.trim_matches('"'))
61 {
62 features.push(feature);
63 }
64 }
65}