diff options
| author | Noratrieb <48135649+Noratrieb@users.noreply.github.com> | 2025-07-26 12:15:19 +0200 |
|---|---|---|
| committer | Noratrieb <48135649+Noratrieb@users.noreply.github.com> | 2025-09-12 20:37:09 +0200 |
| commit | a0bb9cc57db551289cba9fefde086e45cb82733f (patch) | |
| tree | 5e9da15a69c8e93a7cf268ff130b65fdb3cf20e9 /compiler/rustc_target/src/lib.rs | |
| parent | a171994070dc18c3a32fc1aa2d98cf03ae96b63e (diff) | |
| download | rust-a0bb9cc57db551289cba9fefde086e45cb82733f.tar.gz rust-a0bb9cc57db551289cba9fefde086e45cb82733f.zip | |
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.
Diffstat (limited to 'compiler/rustc_target/src/lib.rs')
| -rw-r--r-- | compiler/rustc_target/src/lib.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 91657fef803..c6a23745b04 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -72,3 +72,63 @@ fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> { Some(libdir) => libdir.into(), } } + +macro_rules! target_spec_enum { + ( + $( #[$attr:meta] )* + pub enum $name:ident { + $( + $( #[$variant_attr:meta] )* + $variant:ident = $string:literal, + )* + } + parse_error_type = $parse_error_type:literal; + ) => { + $( #[$attr] )* + #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] + pub enum $name { + $( + $( #[$variant_attr] )* + $variant, + )* + } + + impl FromStr for $name { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + Ok(match s { + $( $string => Self::$variant, )* + _ => { + let all = [$( concat!("'", $string, "'") ),*].join(", "); + return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type)); + } + }) + } + } + + impl $name { + pub fn desc(&self) -> &'static str { + match self { + $( Self::$variant => $string, )* + } + } + } + + impl crate::json::ToJson for $name { + fn to_json(&self) -> crate::json::Json { + self.desc().to_json() + } + } + + crate::json::serde_deserialize_from_str!($name); + + + impl std::fmt::Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.desc()) + } + } + }; +} +use target_spec_enum; |
