tuwunel_core/info/
cargo.rs1use std::sync::OnceLock;
8
9use cargo_toml::{DepsSet, Manifest};
10use tuwunel_macros::cargo_manifest;
11
12use crate::Result;
13
14#[cargo_manifest]
19const WORKSPACE_MANIFEST: &'static str = ();
20#[cargo_manifest(crate = "macros")]
21const MACROS_MANIFEST: &'static str = ();
22#[cargo_manifest(crate = "core")]
23const CORE_MANIFEST: &'static str = ();
24#[cargo_manifest(crate = "database")]
25const DATABASE_MANIFEST: &'static str = ();
26#[cargo_manifest(crate = "service")]
27const SERVICE_MANIFEST: &'static str = ();
28#[cargo_manifest(crate = "admin")]
29const ADMIN_MANIFEST: &'static str = ();
30#[cargo_manifest(crate = "router")]
31const ROUTER_MANIFEST: &'static str = ();
32#[cargo_manifest(crate = "main")]
33const MAIN_MANIFEST: &'static str = ();
34
35static FEATURES: OnceLock<Vec<String>> = OnceLock::new();
39
40static DEPENDENCIES: OnceLock<DepsSet> = OnceLock::new();
43
44#[must_use]
45pub fn dependencies_names() -> Vec<&'static str> {
55 dependencies()
56 .keys()
57 .map(String::as_str)
58 .collect()
59}
60
61pub fn dependencies() -> &'static DepsSet {
71 DEPENDENCIES.get_or_init(|| {
72 init_dependencies().unwrap_or_else(|e| panic!("Failed to initialize dependencies: {e}"))
73 })
74}
75
76pub fn features() -> &'static Vec<String> {
79 FEATURES.get_or_init(|| {
80 init_features().unwrap_or_else(|e| panic!("Failed initialize features: {e}"))
81 })
82}
83
84fn init_features() -> Result<Vec<String>> {
85 let mut features = Vec::new();
86 append_features(&mut features, WORKSPACE_MANIFEST)?;
87 append_features(&mut features, MACROS_MANIFEST)?;
88 append_features(&mut features, CORE_MANIFEST)?;
89 append_features(&mut features, DATABASE_MANIFEST)?;
90 append_features(&mut features, SERVICE_MANIFEST)?;
91 append_features(&mut features, ADMIN_MANIFEST)?;
92 append_features(&mut features, ROUTER_MANIFEST)?;
93 append_features(&mut features, MAIN_MANIFEST)?;
94 features.sort();
95 features.dedup();
96
97 Ok(features)
98}
99
100fn append_features(features: &mut Vec<String>, manifest: &str) -> Result {
101 let manifest = Manifest::from_str(manifest)?;
102 features.extend(manifest.features.keys().cloned());
103
104 Ok(())
105}
106
107fn init_dependencies() -> Result<DepsSet> {
108 let manifest = Manifest::from_str(WORKSPACE_MANIFEST)?;
109 let deps_set = manifest
110 .workspace
111 .as_ref()
112 .expect("manifest has workspace section")
113 .dependencies
114 .clone();
115
116 Ok(deps_set)
117}