use anyhow::Result;
use chrono::prelude::*;
use platform_info::{PlatformInfo, PlatformInfoAPI, UNameAPI};
use serde::Serialize;
use std::fs;
use std::path::Path;
const METADATA_FILE_NAME: &str = "metadata.toml";
#[allow(clippy::doc_markdown)]
#[allow(clippy::needless_raw_strings)]
mod built_info {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
}
fn get_git_hash() -> String {
let Some(hash) = built_info::GIT_COMMIT_HASH_SHORT else {
return "unknown".into();
};
if built_info::GIT_DIRTY == Some(true) {
format!("{hash}-dirty")
} else {
hash.into()
}
}
#[derive(Serialize)]
struct Metadata<'a> {
run: RunMetadata<'a>,
program: ProgramMetadata<'a>,
platform: PlatformMetadata,
}
#[derive(Serialize)]
struct RunMetadata<'a> {
model_path: &'a Path,
datetime: String,
}
impl<'a> RunMetadata<'a> {
fn new(model_path: &'a Path) -> Self {
let dt = Local::now();
Self {
model_path,
datetime: dt.to_rfc2822(),
}
}
}
#[derive(Serialize)]
struct ProgramMetadata<'a> {
name: &'a str,
version: &'a str,
target: &'a str,
is_debug: bool,
rustc_version: &'a str,
build_time_utc: &'a str,
git_commit_hash: String,
}
impl Default for ProgramMetadata<'_> {
fn default() -> Self {
Self {
name: built_info::PKG_NAME,
version: built_info::PKG_VERSION,
target: built_info::TARGET,
is_debug: built_info::DEBUG,
rustc_version: built_info::RUSTC_VERSION,
build_time_utc: built_info::BUILT_TIME_UTC,
git_commit_hash: get_git_hash(),
}
}
}
#[derive(Serialize)]
struct PlatformMetadata {
sysname: String,
nodename: String,
release: String,
version: String,
machine: String,
osname: String,
}
impl Default for PlatformMetadata {
fn default() -> Self {
let info = PlatformInfo::new().expect("Unable to determine platform info");
Self {
sysname: info.sysname().to_string_lossy().into(),
nodename: info.nodename().to_string_lossy().into(),
release: info.release().to_string_lossy().into(),
version: info.version().to_string_lossy().into(),
machine: info.machine().to_string_lossy().into(),
osname: info.osname().to_string_lossy().into(),
}
}
}
pub fn write_metadata(output_path: &Path, model_path: &Path) -> Result<()> {
let metadata = Metadata {
run: RunMetadata::new(model_path),
program: ProgramMetadata::default(),
platform: PlatformMetadata::default(),
};
let file_path = output_path.join(METADATA_FILE_NAME);
fs::write(&file_path, toml::to_string(&metadata)?)?;
Ok(())
}