1use std::fmt;
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub struct Target(pub String);
11
12impl Target {
13 #[must_use]
15 pub fn short(&self) -> String {
16 let parts: Vec<&str> = self.0.split('-').collect();
17 match parts.as_slice() {
18 [arch, _vendor, os, ..] => format!("{arch}-{os}"),
19 [arch, os] => format!("{arch}-{os}"),
20 _ => self.0.clone(),
21 }
22 }
23}
24
25impl fmt::Display for Target {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.write_str(&self.0)
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
33pub struct RustcVersion {
34 pub version: semver::Version,
36 pub commit_hash: String,
38 pub llvm_version: String,
40}
41
42impl RustcVersion {
43 #[must_use]
45 pub fn short(&self) -> String {
46 self.version.to_string()
47 }
48}
49
50impl fmt::Display for RustcVersion {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 write!(f, "{} ({})", self.version, self.commit_hash)
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema)]
58pub struct Profile {
59 pub opt_level: String,
61 pub debuginfo: u32,
63 pub debug_assertions: bool,
65 pub overflow_checks: bool,
67 pub panic: PanicStrategy,
69 #[serde(default, skip_serializing_if = "StripLevel::is_none")]
74 pub strip: StripLevel,
75}
76
77impl Profile {
78 #[must_use]
80 pub fn is_debug(&self) -> bool {
81 self.opt_level == "0" && self.debug_assertions
82 }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema)]
87pub enum PanicStrategy {
88 Unwind,
90 Abort,
92}
93
94impl PanicStrategy {
95 #[must_use]
97 pub const fn as_str(&self) -> &str {
98 match self {
99 Self::Unwind => "unwind",
100 Self::Abort => "abort",
101 }
102 }
103}
104
105impl fmt::Display for PanicStrategy {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 f.write_str(self.as_str())
108 }
109}
110
111#[derive(
117 Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema,
118)]
119#[serde(rename_all = "lowercase")]
120pub enum StripLevel {
121 #[default]
123 None,
124 Debuginfo,
126 Symbols,
128}
129
130impl StripLevel {
131 #[must_use]
133 pub const fn as_str(&self) -> &str {
134 match self {
135 Self::None => "none",
136 Self::Debuginfo => "debuginfo",
137 Self::Symbols => "symbols",
138 }
139 }
140
141 #[must_use]
143 pub const fn is_none(&self) -> bool {
144 matches!(self, Self::None)
145 }
146}
147
148impl fmt::Display for StripLevel {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 f.write_str(self.as_str())
151 }
152}