use std::fmt;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Target(pub String);
impl Target {
#[must_use]
pub fn short(&self) -> String {
let parts: Vec<&str> = self.0.split('-').collect();
match parts.as_slice() {
[arch, _vendor, os, ..] => format!("{arch}-{os}"),
[arch, os] => format!("{arch}-{os}"),
_ => self.0.clone(),
}
}
}
impl fmt::Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct RustcVersion {
pub version: semver::Version,
pub commit_hash: String,
pub llvm_version: String,
}
impl RustcVersion {
#[must_use]
pub fn short(&self) -> String {
self.version.to_string()
}
}
impl fmt::Display for RustcVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ({})", self.version, self.commit_hash)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema)]
pub struct Profile {
pub opt_level: String,
pub debuginfo: u32,
pub debug_assertions: bool,
pub overflow_checks: bool,
pub panic: PanicStrategy,
#[serde(default, skip_serializing_if = "StripLevel::is_none")]
pub strip: StripLevel,
}
impl Profile {
#[must_use]
pub fn is_debug(&self) -> bool {
self.opt_level == "0" && self.debug_assertions
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema)]
pub enum PanicStrategy {
Unwind,
Abort,
}
impl PanicStrategy {
#[must_use]
pub const fn as_str(&self) -> &str {
match self {
Self::Unwind => "unwind",
Self::Abort => "abort",
}
}
}
impl fmt::Display for PanicStrategy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(
Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema,
)]
#[serde(rename_all = "lowercase")]
pub enum StripLevel {
#[default]
None,
Debuginfo,
Symbols,
}
impl StripLevel {
#[must_use]
pub const fn as_str(&self) -> &str {
match self {
Self::None => "none",
Self::Debuginfo => "debuginfo",
Self::Symbols => "symbols",
}
}
#[must_use]
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
}
impl fmt::Display for StripLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}