use serde::{Deserialize, Serialize};
use super::capabilities::{ArchiverCapabilities, Capability, CompilerCapabilities};
use super::identity::{ArchiverIdentity, CompilerIdentity};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ToolchainDetectionReport {
pub cxx: ToolDetection<CompilerIdentity, CompilerCapabilities>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cc: Option<ToolDetection<CompilerIdentity, CompilerCapabilities>>,
pub ar: ToolDetection<ArchiverIdentity, ArchiverCapabilities>,
}
impl ToolchainDetectionReport {
pub fn as_json(&self) -> serde_json::Value {
let mut obj = serde_json::Map::new();
obj.insert(
"cxx".to_owned(),
serde_json::json!({
"path": self.cxx.path.as_str().to_owned(),
"identity": self.cxx.identity.as_json(),
"capabilities": cxx_capabilities_as_json(&self.cxx.capabilities),
}),
);
if let Some(cc) = &self.cc {
obj.insert(
"cc".to_owned(),
serde_json::json!({
"path": cc.path.as_str().to_owned(),
"identity": cc.identity.as_json(),
"capabilities": cxx_capabilities_as_json(&cc.capabilities),
}),
);
}
obj.insert(
"ar".to_owned(),
serde_json::json!({
"path": self.ar.path.as_str().to_owned(),
"identity": self.ar.identity.as_json(),
"capabilities": ar_capabilities_as_json(&self.ar.capabilities),
}),
);
serde_json::Value::Object(obj)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ToolDetection<I, C> {
pub path: camino::Utf8PathBuf,
pub identity: I,
pub capabilities: C,
}
pub(crate) fn cxx_capabilities_as_json(caps: &CompilerCapabilities) -> serde_json::Value {
let CompilerCapabilities {
gcc_style_flags,
msvc_style_flags,
depfile_mmd_mf,
std_flag,
cxx_standard_17,
c_standard_11,
} = caps;
let mut entries: [(&'static str, &Capability); 6] = [
("gcc_style_flags", gcc_style_flags),
("msvc_style_flags", msvc_style_flags),
("depfile_mmd_mf", depfile_mmd_mf),
("std_flag", std_flag),
("cxx_standard_17", cxx_standard_17),
("c_standard_11", c_standard_11),
];
capabilities_to_json(&mut entries)
}
pub(crate) fn ar_capabilities_as_json(caps: &ArchiverCapabilities) -> serde_json::Value {
let ArchiverCapabilities {
ar_crs,
static_library_output,
} = caps;
let mut entries: [(&'static str, &Capability); 2] = [
("ar_crs", ar_crs),
("static_library_output", static_library_output),
];
capabilities_to_json(&mut entries)
}
fn capabilities_to_json(entries: &mut [(&'static str, &Capability)]) -> serde_json::Value {
entries.sort_by_key(|(key, _)| *key);
let mut obj = serde_json::Map::new();
for (key, cap) in entries {
obj.insert(
(*key).to_owned(),
serde_json::json!({
"supported": cap.supported,
"source": cap.source.as_key(),
}),
);
}
serde_json::Value::Object(obj)
}