1use anyhow::Result;
3use chrono::prelude::*;
4use platform_info::{PlatformInfo, PlatformInfoAPI, UNameAPI};
5use serde::Serialize;
6use std::fs;
7use std::path::Path;
8
9const METADATA_FILE_NAME: &str = "metadata.toml";
11
12mod built_info {
14 include!(concat!(env!("OUT_DIR"), "/built.rs"));
16}
17
18fn get_git_hash() -> String {
20 let Some(hash) = built_info::GIT_COMMIT_HASH_SHORT else {
21 return "unknown".into();
22 };
23
24 if built_info::GIT_DIRTY == Some(true) {
25 format!("{hash}-dirty")
26 } else {
27 hash.into()
28 }
29}
30
31#[derive(Serialize)]
33struct Metadata<'a> {
34 run: RunMetadata<'a>,
35 program: ProgramMetadata<'a>,
36 platform: PlatformMetadata,
37}
38
39#[derive(Serialize)]
41struct RunMetadata<'a> {
42 model_path: &'a Path,
44 datetime: String,
46}
47
48impl<'a> RunMetadata<'a> {
49 fn new(model_path: &'a Path) -> Self {
50 let dt = Local::now();
51 Self {
52 model_path,
53 datetime: dt.to_rfc2822(),
54 }
55 }
56}
57
58#[derive(Serialize)]
59struct ProgramMetadata<'a> {
60 name: &'a str,
62 version: &'a str,
64 target: &'a str,
66 is_debug: bool,
68 rustc_version: &'a str,
70 build_time_utc: &'a str,
72 git_commit_hash: String,
74}
75
76impl Default for ProgramMetadata<'_> {
77 fn default() -> Self {
78 Self {
79 name: built_info::PKG_NAME,
80 version: built_info::PKG_VERSION,
81 target: built_info::TARGET,
82 is_debug: built_info::DEBUG,
83 rustc_version: built_info::RUSTC_VERSION,
84 build_time_utc: built_info::BUILT_TIME_UTC,
85 git_commit_hash: get_git_hash(),
86 }
87 }
88}
89
90#[derive(Serialize)]
94struct PlatformMetadata {
95 sysname: String,
96 nodename: String,
97 release: String,
98 version: String,
99 machine: String,
100 osname: String,
101}
102
103impl Default for PlatformMetadata {
104 fn default() -> Self {
105 let info = PlatformInfo::new().expect("Unable to determine platform info");
106 Self {
107 sysname: info.sysname().to_string_lossy().into(),
108 nodename: info.nodename().to_string_lossy().into(),
109 release: info.release().to_string_lossy().into(),
110 version: info.version().to_string_lossy().into(),
111 machine: info.machine().to_string_lossy().into(),
112 osname: info.osname().to_string_lossy().into(),
113 }
114 }
115}
116
117pub fn write_metadata(output_path: &Path, model_path: &Path) -> Result<()> {
119 let metadata = Metadata {
120 run: RunMetadata::new(model_path),
121 program: ProgramMetadata::default(),
122 platform: PlatformMetadata::default(),
123 };
124 let file_path = output_path.join(METADATA_FILE_NAME);
125 fs::write(&file_path, toml::to_string(&metadata)?)?;
126
127 Ok(())
128}