use anyhow::Result;
use serde::Serialize;
use std::fmt;
#[derive(Debug, Clone, Serialize)]
pub struct VergenInfo {
pub build_timestamp: String,
pub build_semver: String,
pub rustc_channel: String,
pub rustc_commit_date: String,
pub rustc_commit_hash: String,
pub rustc_host_triple: String,
pub rustc_llvm_version: String,
pub rustc_semver: String,
pub cargo_features: String,
pub cargo_profile: String,
pub cargo_target_triple: String,
pub git_branch: String,
pub git_commit_timestamp: String,
pub git_semver: String,
pub git_sha: String,
}
impl Default for VergenInfo {
fn default() -> Self {
Self {
build_semver: env!("VERGEN_BUILD_SEMVER").to_string(),
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL").to_string(),
rustc_commit_date: env!("VERGEN_RUSTC_COMMIT_DATE").to_string(),
rustc_commit_hash: env!("VERGEN_RUSTC_COMMIT_HASH").to_string(),
rustc_host_triple: env!("VERGEN_RUSTC_HOST_TRIPLE").to_string(),
rustc_llvm_version: env!("VERGEN_RUSTC_LLVM_VERSION").to_string(),
rustc_semver: env!("VERGEN_RUSTC_SEMVER").to_string(),
cargo_features: env!("VERGEN_CARGO_FEATURES").to_string(),
cargo_profile: env!("VERGEN_CARGO_PROFILE").to_string(),
cargo_target_triple: env!("VERGEN_CARGO_TARGET_TRIPLE").to_string(),
git_branch: env!("VERGEN_GIT_BRANCH").to_string(),
git_commit_timestamp: env!("VERGEN_GIT_COMMIT_TIMESTAMP").to_string(),
git_semver: env!("VERGEN_GIT_SEMVER").to_string(),
git_sha: env!("VERGEN_GIT_SHA").to_string(),
}
}
}
impl fmt::Display for VergenInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "{:<20} {}", "Build Timestamp:", self.build_timestamp)?;
writeln!(f, "{:<20} {}", "Build Version:", self.build_semver)?;
writeln!(f, "{:<20} {}", "Commit SHA:", self.git_sha)?;
writeln!(f, "{:<20} {}", "Commit Date:", self.git_commit_timestamp)?;
writeln!(f, "{:<20} {}", "Commit Branch:", self.git_branch)?;
writeln!(f, "{:<20} {}", "rustc Version:", self.rustc_semver)?;
writeln!(f, "{:<20} {}", "rustc Channel:", self.rustc_channel)?;
writeln!(f, "{:<20} {}", "rustc Host Triple:", self.rustc_host_triple)?;
writeln!(f, "{:<20} {}", "rustc Commit SHA:", self.rustc_commit_hash)?;
writeln!(
f,
"{:<20} {}",
"cargo Target Triple:", self.cargo_target_triple
)?;
writeln!(f, "{:<20} {}", "cargo Profile:", self.cargo_profile)?;
Ok(())
}
}
impl VergenInfo {
pub fn to_json(&self) -> Result<String> {
Ok(serde_json::to_string_pretty(self)?)
}
}
#[derive(clap::Args, Debug, Clone)]
pub struct Version {
#[clap(long)]
json: bool,
}
impl Version {
pub fn print(&self) -> Result<()> {
let info = VergenInfo::default();
if self.json {
println!("{}", info.to_json()?);
} else {
println!("{}", info);
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display() {
let info = VergenInfo::default();
println!("{}", info);
}
#[test]
fn json() {
let info = VergenInfo::default();
println!("{}", info.to_json().unwrap());
}
#[test]
fn verify_app() {
#[derive(Debug, clap::Parser)]
struct Cli {
#[clap(flatten)]
version: Version,
}
use clap::CommandFactory;
Cli::command().debug_assert()
}
}