use std::{fmt::Display, future::Future, process::ExitCode};
use crate::common::{constants::CRATE_VERSION, message::CommitHash, result::DynResult};
shadow_rs::shadow!(build);
#[expect(clippy::const_is_empty)]
pub(super) const COMMIT_HASH: Option<CommitHash> = if build::COMMIT_HASH.is_empty() {
None
} else {
Some(CommitHash::from_hex_str(build::COMMIT_HASH))
};
const TAG_BRANCH: &str = {
#[expect(clippy::const_is_empty)]
if build::TAG.is_empty() {
#[expect(clippy::const_is_empty)]
if build::BRANCH.is_empty() {
""
} else {
shadow_rs::concatcp!("\nbranch: ", build::BRANCH)
}
} else {
shadow_rs::concatcp!("\ntag: ", build::TAG)
}
};
const COMMIT: &str = {
const _COMMIT: &str = if COMMIT_HASH.is_some() {
COMMIT_HASH.as_ref().unwrap().as_str()
} else {
""
};
if COMMIT_HASH.is_some() {
shadow_rs::concatcp!(
"\ncommit: ",
_COMMIT,
"\ncommit time: ",
build::COMMIT_DATE,
)
} else {
""
}
};
pub(super) const CLAP_LONG_VERSION: &str = shadow_rs::concatcp!(
CRATE_VERSION,
TAG_BRANCH,
COMMIT,
"\nbuild target: ",
build::BUILD_TARGET,
"\nrust version: ",
build::RUST_VERSION,
"\nbuild os: ",
build::BUILD_OS,
);
#[allow(dead_code)]
#[inline]
pub(crate) fn run(fut: impl Future<Output = DynResult<()>>) -> DynResult<()> {
run_with_runtime(&create_runtime()?, fut)
}
#[inline]
fn create_runtime() -> std::io::Result<tokio::runtime::Runtime> {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
}
#[inline]
fn run_with_runtime<Err>(
runtime: &tokio::runtime::Runtime,
fut: impl Future<Output = Result<(), Err>>,
) -> Result<(), Err> {
runtime.block_on(fut)
}
#[inline]
pub(crate) fn print_error<const LOG_TO_STDOUT: bool, Err: Display>(
result: Result<(), Err>,
) -> std::process::ExitCode {
match result {
Ok(()) => ExitCode::SUCCESS,
Err(err) => {
if LOG_TO_STDOUT {
println!("Error: {err}");
} else {
log::error!("Exiting with error: {err}");
}
ExitCode::FAILURE
}
}
}