Skip to main content

tuwunel_core/info/
version.rs

1//! one true function for returning the application version with the necessary
2//! TUWUNEL_VERSION_EXTRA env variables used if specified
3//!
4//! Set the environment variable `TUWUNEL_VERSION_EXTRA` to any UTF-8 string
5//! to include it in parenthesis after the SemVer version. A common value are
6//! git commit hashes.
7
8use std::sync::OnceLock;
9
10static BRANDING: &str = "Tuwunel";
11static SEMANTIC: &str = env!("CARGO_PKG_VERSION");
12tuwunel_macros::git_commit! {}
13tuwunel_macros::git_semantic! {}
14
15static VERSION: OnceLock<String> = OnceLock::new();
16static USER_AGENT: OnceLock<String> = OnceLock::new();
17
18#[inline]
19#[must_use]
20pub fn name() -> &'static str { BRANDING }
21
22#[inline]
23pub fn version() -> &'static str { VERSION.get_or_init(init_version) }
24
25#[inline]
26pub fn user_agent() -> &'static str { USER_AGENT.get_or_init(init_user_agent) }
27
28fn init_user_agent() -> String { format!("{}/{}", name(), semantic()) }
29
30fn init_version() -> String {
31	option_env!("TUWUNEL_VERSION_EXTRA")
32		.or(option_env!("CONDUWUIT_VERSION_EXTRA"))
33		.or(option_env!("CONDUIT_VERSION_EXTRA"))
34		.map_or_else(detailed, |extra| {
35			extra
36				.is_empty()
37				.then(detailed)
38				.unwrap_or_else(|| format!("{} ({extra})", detailed()))
39		})
40}
41
42fn detailed() -> String {
43	let tag_dirty = semantic()
44		.rsplit_once('-')
45		.is_some_and(|(_, s)| !s.is_empty());
46
47	if !GIT_COMMIT.is_empty() && tag_dirty {
48		format!("{} ({})", semantic(), GIT_COMMIT)
49	} else {
50		semantic().to_owned()
51	}
52}
53
54fn semantic() -> &'static str {
55	if !GIT_SEMANTIC.is_empty() {
56		GIT_SEMANTIC
57	} else {
58		SEMANTIC
59	}
60}