Skip to main content

tuwunel_core/info/
rustc.rs

1//! Rust compiler metadata captured for the running build.
2//!
3//! Participating project crates contribute their compiler flags through
4//! build-time macros and static initialization, allowing project-wide compiler
5//! information to be queried here.
6
7use std::{
8	collections::BTreeMap,
9	mem::replace,
10	sync::{Mutex, OnceLock},
11};
12
13// Capture rustc version during compilation.
14tuwunel_macros::rustc_version! {}
15
16/// Compiler flags captured for participating project crates.
17///
18/// Crate-local `rustc_flags_capture` macros populate this map during static
19/// initialization. It is public only for that registration path and must not be
20/// modified elsewhere.
21pub static FLAGS: Mutex<BTreeMap<&str, &[&str]>> = Mutex::new(BTreeMap::new());
22
23/// Processed list of enabled features across participating project crates. This
24/// is generated from the data in FLAGS.
25static FEATURES: OnceLock<Vec<&'static str>> = OnceLock::new();
26
27/// List of features enabled for the project.
28pub fn features() -> &'static Vec<&'static str> { FEATURES.get_or_init(init_features) }
29
30/// Version of the rustc compiler used during build.
31#[inline]
32#[must_use]
33pub fn version() -> Option<&'static str> {
34	RUSTC_VERSION
35		.len()
36		.gt(&0)
37		.then_some(RUSTC_VERSION)
38}
39
40fn init_features() -> Vec<&'static str> {
41	let mut features = Vec::new();
42	FLAGS
43		.lock()
44		.expect("locked")
45		.iter()
46		.for_each(|(_, flags)| append_features(&mut features, flags));
47
48	features.sort_unstable();
49	features.dedup();
50	features
51}
52
53fn append_features(features: &mut Vec<&'static str>, flags: &[&'static str]) {
54	let mut next_is_cfg = false;
55	for flag in flags {
56		let is_cfg = *flag == "--cfg";
57		let is_feature = flag.starts_with("feature=");
58		if replace(&mut next_is_cfg, is_cfg)
59			&& is_feature
60			&& let Some(feature) = flag
61				.split_once('=')
62				.map(|(_, feature)| feature.trim_matches('"'))
63		{
64			features.push(feature);
65		}
66	}
67}