include!(concat!(env!("OUT_DIR"), "/metadata.rs"));
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ToolchainFingerprint {
pub lean_version: &'static str,
pub resolved_version: &'static str,
pub header_sha256: &'static str,
pub fixture_sha256: &'static str,
pub host_triple: &'static str,
}
impl ToolchainFingerprint {
#[must_use]
pub const fn current() -> Self {
Self {
lean_version: lean_rs_sys::LEAN_VERSION,
resolved_version: lean_rs_sys::LEAN_RESOLVED_VERSION,
header_sha256: lean_rs_sys::LEAN_HEADER_DIGEST,
fixture_sha256: LAKE_FIXTURE_DIGEST,
host_triple: HOST_TRIPLE,
}
}
#[must_use]
pub fn is_supported(&self) -> bool {
lean_rs_sys::supported_for(self.lean_version).is_some()
}
}
impl Default for ToolchainFingerprint {
fn default() -> Self {
Self::current()
}
}
#[cfg(test)]
mod tests {
use super::ToolchainFingerprint;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash as _, Hasher as _};
#[test]
fn current_round_trips_through_clone() {
let a = ToolchainFingerprint::current();
let b = a.clone();
assert_eq!(a, b);
}
#[test]
fn fingerprint_hash_is_deterministic() {
let a = ToolchainFingerprint::current();
let b = ToolchainFingerprint::current();
let mut ha = DefaultHasher::new();
let mut hb = DefaultHasher::new();
a.hash(&mut ha);
b.hash(&mut hb);
assert_eq!(ha.finish(), hb.finish());
}
#[test]
fn distinct_header_digest_changes_fingerprint() {
let a = ToolchainFingerprint::current();
let b = ToolchainFingerprint {
header_sha256: "0000000000000000000000000000000000000000000000000000000000000000",
..a
};
assert_ne!(a, b);
}
#[test]
fn current_is_in_supported_window() {
assert!(ToolchainFingerprint::current().is_supported());
}
#[test]
fn synthetic_unknown_version_is_not_supported() {
let mut fp = ToolchainFingerprint::current();
fp.lean_version = "0.0.0-test";
assert!(!fp.is_supported());
}
}