use std::collections::BTreeMap;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{Diagnostic, Report};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct MatrixReport {
pub schema_version: u32,
pub platform_targets: BTreeMap<String, PlatformTargetGroup>,
pub runtime_versions: BTreeMap<String, Vec<RuntimeVersionEntry>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub diagnostics: Vec<Diagnostic>,
}
impl Report for MatrixReport {
const COMMAND: &'static str = "matrix";
fn schema_version(&self) -> u32 {
self.schema_version
}
fn diagnostics(&self) -> &[Diagnostic] {
&self.diagnostics
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct PlatformTargetGroup {
pub kind: PlatformTargetKind,
pub source: String,
pub targets: Vec<PlatformTarget>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum PlatformTargetKind {
Napi,
Maturin,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct PlatformTarget {
pub triple: String,
pub platform: String,
pub arch: String,
pub abi: Option<String>,
pub host_runner: String,
pub use_cross: bool,
pub artifact_name: String,
pub package_dir: String,
pub package_name: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct RuntimeVersionEntry {
pub ecosystem: RuntimeEcosystem,
pub field: String,
pub range: String,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum RuntimeEcosystem {
Npm,
Python,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_matrix_report_serializes_with_no_diagnostics_key() {
let report = MatrixReport {
schema_version: 1,
platform_targets: std::collections::BTreeMap::new(),
runtime_versions: std::collections::BTreeMap::new(),
diagnostics: Vec::new(),
};
let json = serde_json::to_value(&report).unwrap();
assert_eq!(
json,
serde_json::json!({
"schemaVersion": 1,
"platformTargets": {},
"runtimeVersions": {}
})
);
}
#[test]
fn platform_target_kind_rejects_unknown_dotnet_aot_variant() {
let raw = serde_json::json!({
"kind": "dotnet-aot",
"source": "whatever",
"targets": []
});
let result: Result<PlatformTargetGroup, _> = serde_json::from_value(raw);
assert!(
result.is_err(),
"expected deserialization of kind=dotnet-aot to fail"
);
}
#[test]
fn runtime_ecosystem_rejects_unknown_dotnet_variant() {
let raw = serde_json::json!({
"ecosystem": "dotnet",
"field": "whatever",
"range": "whatever"
});
let result: Result<RuntimeVersionEntry, _> = serde_json::from_value(raw);
assert!(
result.is_err(),
"expected deserialization of ecosystem=dotnet to fail"
);
}
}