rust/compiler/rustc_target/src/json.rs
Nilstrieb 5bcb66cfb3 Add metadata to targets
This adds four pieces of metadata to every target:
- description
- tier
- host tools
- std

This information is currently scattered across target docs and both
- not machine readable, making validation harder
- sometimes subtly encoding by the table it's in, causing mistakes and
  making it harder to review changes to the properties

By putting it in the compiler, we improve this. Later, we will use this
canonical information to generate target documentation from it.
2024-03-10 20:46:08 +01:00

135 lines
3.2 KiB
Rust

use std::borrow::Cow;
use std::collections::BTreeMap;
pub use serde_json::Value as Json;
use serde_json::{json, Map, Number};
use crate::spec::TargetMetadata;
pub trait ToJson {
fn to_json(&self) -> Json;
}
impl ToJson for Json {
fn to_json(&self) -> Json {
self.clone()
}
}
macro_rules! to_json_impl_num {
($($t:ty), +) => (
$(impl ToJson for $t {
fn to_json(&self) -> Json {
Json::Number(Number::from(*self))
}
})+
)
}
to_json_impl_num! { isize, i8, i16, i32, i64, usize, u8, u16, u32, u64 }
impl ToJson for bool {
fn to_json(&self) -> Json {
Json::Bool(*self)
}
}
impl ToJson for str {
fn to_json(&self) -> Json {
Json::String(self.to_owned())
}
}
impl ToJson for String {
fn to_json(&self) -> Json {
Json::String(self.to_owned())
}
}
impl<'a> ToJson for Cow<'a, str> {
fn to_json(&self) -> Json {
Json::String(self.to_string())
}
}
impl<A: ToJson> ToJson for [A] {
fn to_json(&self) -> Json {
Json::Array(self.iter().map(|elt| elt.to_json()).collect())
}
}
impl<A: ToJson> ToJson for Vec<A> {
fn to_json(&self) -> Json {
Json::Array(self.iter().map(|elt| elt.to_json()).collect())
}
}
impl<'a, A: ToJson> ToJson for Cow<'a, [A]>
where
[A]: ToOwned,
{
fn to_json(&self) -> Json {
Json::Array(self.iter().map(|elt| elt.to_json()).collect())
}
}
impl<T: ToString, A: ToJson> ToJson for BTreeMap<T, A> {
fn to_json(&self) -> Json {
let mut d = Map::new();
for (key, value) in self {
d.insert(key.to_string(), value.to_json());
}
Json::Object(d)
}
}
impl<A: ToJson> ToJson for Option<A> {
fn to_json(&self) -> Json {
match *self {
None => Json::Null,
Some(ref value) => value.to_json(),
}
}
}
impl ToJson for crate::abi::call::Conv {
fn to_json(&self) -> Json {
let buf: String;
let s = match self {
Self::C => "C",
Self::Rust => "Rust",
Self::Cold => "Cold",
Self::PreserveMost => "PreserveMost",
Self::PreserveAll => "PreserveAll",
Self::ArmAapcs => "ArmAapcs",
Self::CCmseNonSecureCall => "CCmseNonSecureCall",
Self::Msp430Intr => "Msp430Intr",
Self::PtxKernel => "PtxKernel",
Self::X86Fastcall => "X86Fastcall",
Self::X86Intr => "X86Intr",
Self::X86Stdcall => "X86Stdcall",
Self::X86ThisCall => "X86ThisCall",
Self::X86VectorCall => "X86VectorCall",
Self::X86_64SysV => "X86_64SysV",
Self::X86_64Win64 => "X86_64Win64",
Self::AvrInterrupt => "AvrInterrupt",
Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
Self::RiscvInterrupt { kind } => {
buf = format!("RiscvInterrupt({})", kind.as_str());
&buf
}
};
Json::String(s.to_owned())
}
}
impl ToJson for TargetMetadata {
fn to_json(&self) -> Json {
json!({
"description": self.description,
"tier": self.tier,
"host_tools": self.host_tools,
"std": self.std,
})
}
}