Skip to content

Commit c29f5b9

Browse files
committed
Introduce target_spec_enum macro to avoid duplication
With this macro we only need to enumerate every variant once. This saves a lot of duplication already between the definition, the `FromStr` impl and the `ToJson` impl. It also enables us to do further things with it like JSON schema generation.
1 parent f32b232 commit c29f5b9

File tree

2 files changed

+242
-712
lines changed

2 files changed

+242
-712
lines changed

compiler/rustc_target/src/lib.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,64 @@ fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> {
7272
Some(libdir) => libdir.into(),
7373
}
7474
}
75+
76+
macro_rules! target_spec_enum {
77+
(
78+
$( #[$attr:meta] )*
79+
pub enum $name:ident {
80+
$(
81+
$( #[$variant_attr:meta] )*
82+
$variant:ident = $string:literal,
83+
)*
84+
}
85+
parse_error_type = $parse_error_type:literal;
86+
87+
) => {
88+
$( #[$attr] )*
89+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
90+
pub enum $name {
91+
$(
92+
$( #[$variant_attr] )*
93+
$variant,
94+
)*
95+
}
96+
97+
impl FromStr for $name {
98+
type Err = String;
99+
100+
fn from_str(s: &str) -> Result<Self, Self::Err> {
101+
Ok(match s {
102+
$( $string => Self::$variant, )*
103+
_ => {
104+
let all = [$( concat!("'", $string, "'") ),*].join(", ");
105+
return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type));
106+
}
107+
})
108+
}
109+
}
110+
111+
impl $name {
112+
pub fn desc(&self) -> &'static str {
113+
match self {
114+
$( Self::$variant => $string, )*
115+
}
116+
}
117+
}
118+
119+
impl crate::json::ToJson for $name {
120+
fn to_json(&self) -> crate::json::Json {
121+
self.desc().to_json()
122+
}
123+
}
124+
125+
crate::json::serde_deserialize_from_str!($name);
126+
127+
128+
impl std::fmt::Display for $name {
129+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130+
f.write_str(self.desc())
131+
}
132+
}
133+
};
134+
}
135+
use target_spec_enum;

0 commit comments

Comments
 (0)