use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
println!("cargo::rerun-if-changed=build.rs");
println!("cargo::rerun-if-env-changed=EXFILTRATE_GIT_SHA");
let target = std::env::var("TARGET").unwrap_or_default();
let profile = std::env::var("PROFILE").unwrap_or_default();
println!("cargo::rustc-env=EXFILTRATE_TARGET={target}");
println!("cargo::rustc-env=EXFILTRATE_PROFILE={profile}");
println!(
"cargo::rustc-env=EXFILTRATE_BUILD_TIMESTAMP={}",
timestamp()
);
let sha = std::env::var("EXFILTRATE_GIT_SHA")
.ok()
.filter(|sha| !sha.is_empty())
.or_else(git_sha)
.unwrap_or_default();
println!("cargo::rustc-env=EXFILTRATE_GIT_SHA={sha}");
}
fn git_sha() -> Option<String> {
let output = std::process::Command::new("git")
.args(["rev-parse", "--short", "HEAD"])
.output()
.ok()?;
if !output.status.success() {
return None;
}
let sha = String::from_utf8(output.stdout).ok()?.trim().to_string();
if sha.is_empty() { None } else { Some(sha) }
}
fn timestamp() -> String {
let Ok(since_epoch) = SystemTime::now().duration_since(UNIX_EPOCH) else {
return String::new();
};
let seconds = since_epoch.as_secs() as i64;
let days = seconds.div_euclid(86_400);
let time_of_day = seconds.rem_euclid(86_400);
let (year, month, day) = civil_from_days(days);
format!(
"{year:04}-{month:02}-{day:02}T{:02}:{:02}:{:02}Z",
time_of_day / 3600,
(time_of_day % 3600) / 60,
time_of_day % 60
)
}
fn civil_from_days(days: i64) -> (i64, u32, u32) {
let z = days + 719_468;
let era = z.div_euclid(146_097);
let day_of_era = z.rem_euclid(146_097);
let year_of_era =
(day_of_era - day_of_era / 1460 + day_of_era / 36_524 - day_of_era / 146_096) / 365;
let year = year_of_era + era * 400;
let day_of_year = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100);
let shifted_month = (5 * day_of_year + 2) / 153;
let day = (day_of_year - (153 * shifted_month + 2) / 5 + 1) as u32;
let month = if shifted_month < 10 {
shifted_month + 3
} else {
shifted_month - 9
} as u32;
(if month <= 2 { year + 1 } else { year }, month, day)
}