Skip to main content

sioul_core/
build.rs

1// SPDX-License-Identifier: GPL-3.0-or-later
2// Copyright © 2026 Aurélien Pierre
3
4//! The build behind this Sioul (docs/building.md, "Which build"): its version
5//! and the commit it was built from, said in `sioul --version`, in Settings,
6//! in this device's entry among your devices and in its records, so that what
7//! each device wrote can be traced to the code that wrote it.
8
9/// The version, as `Cargo.toml` says it: "0.0.3".
10pub const VERSION: &str = env!("CARGO_PKG_VERSION");
11
12/// The commit, as the build found it (`build.rs`): twelve characters of its
13/// hash ("eff8661abcde"), "-dirty" after them when the tree held changes not
14/// committed; `SIOUL_COMMIT`'s value where the repository was not there; "unknown".
15pub const COMMIT: &str = env!("SIOUL_BUILD_COMMIT");
16
17/// Both, as said everywhere: "0.0.3 (eff8661abcde)".
18pub const DESCRIBED: &str = concat!(env!("CARGO_PKG_VERSION"), " (", env!("SIOUL_BUILD_COMMIT"), ")");
19
20/// A build as an entry or a record says it, in words: "0.0.3 (eff8661abcde)";
21/// the version alone when the commit is unsaid (an older Sioul); "" when neither is.
22pub fn described(version: &str, commit: &str) -> String {
23    match (version.trim(), commit.trim()) {
24        ("", _) => String::new(),
25        (version, "") => version.to_string(),
26        (version, commit) => format!("{version} ({commit})"),
27    }
28}
29
30/// Whether `version` comes before `than`, number by number ("0.0.2" before
31/// "0.0.10"); neither when either does not read as numbers (nothing said).
32pub fn older(version: &str, than: &str) -> bool {
33    let numbers = |v: &str| -> Option<Vec<u64>> { v.trim().split(['.', '-', '+']).take(3).map(|n| n.parse().ok()).collect() };
34    match (numbers(version), numbers(than)) {
35        (Some(a), Some(b)) if !a.is_empty() && !b.is_empty() => a < b,
36        _ => false,
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn the_build_is_said_and_compared() {
46        assert!(!VERSION.is_empty() && !COMMIT.is_empty());
47        assert!(COMMIT == "unknown" || COMMIT.trim_end_matches("-dirty").chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '.'), "{COMMIT}");
48        assert_eq!(DESCRIBED, format!("{VERSION} ({COMMIT})"));
49        assert_eq!(described("0.0.3", "eff8661abcde"), "0.0.3 (eff8661abcde)");
50        assert_eq!(described("0.0.2", ""), "0.0.2", "an older Sioul says its version alone");
51        assert_eq!(described("", ""), "");
52        assert!(older("0.0.2", "0.0.3") && older("0.0.9", "0.0.10") && older("0.9.0", "1.0.0"));
53        assert!(!older("0.0.3", "0.0.3") && !older("0.0.4", "0.0.3"));
54        assert!(!older("", "0.0.3") && !older("0.0.3", "") && !older("next", "0.0.3"), "what does not read is never said older");
55    }
56}