diff options
Diffstat (limited to 'compiler/rustc_target/src/lib.rs')
| -rw-r--r-- | compiler/rustc_target/src/lib.rs | 63 | 
1 files changed, 63 insertions, 0 deletions
| diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 91657fef803..8c6a77cba8b 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -72,3 +72,66 @@ 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)] + #[derive(schemars::JsonSchema)] + pub enum $Name { + $( + $( #[$variant_attr] )* + #[serde(rename = $string)] // for JSON schema generation only + $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 const ALL: &'static [$Name] = &[ $( $Name::$Variant, )* ]; + 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; | 
