use serde::Serialize;
use crate::bus::BUS_ABI;
use crate::runtime::spec::{ContractUse, Direction, RuntimeBehavior};
pub const EMIT_SCHEMA: &str = "phoxal.emit-apis/v0";
#[derive(Debug, Serialize)]
pub struct RuntimeMetadata {
pub schema: &'static str,
pub artifact: Artifact,
pub framework: Framework,
pub api_version: String,
pub bus_abi: String,
pub required_contracts: Vec<ContractView>,
pub config_schema: serde_json::Value,
}
#[derive(Debug, Serialize)]
pub struct Artifact {
pub kind: &'static str,
pub id: String,
}
#[derive(Debug, Serialize)]
pub struct Framework {
pub version: String,
}
#[derive(Debug, Serialize)]
pub struct ContractView {
pub family: String,
pub topic: String,
pub direction: Direction,
}
impl From<&ContractUse> for ContractView {
fn from(c: &ContractUse) -> Self {
ContractView {
family: c.family.to_string(),
topic: c.topic.to_string(),
direction: c.direction,
}
}
}
pub fn runtime_metadata<R: RuntimeBehavior>() -> RuntimeMetadata {
let required_contracts = R::FIELD_CONTRACTS
.iter()
.chain(R::SERVER_CONTRACTS.iter())
.map(ContractView::from)
.collect();
RuntimeMetadata {
schema: EMIT_SCHEMA,
artifact: Artifact {
kind: "runtime",
id: R::ID.to_string(),
},
framework: Framework {
version: env!("CARGO_PKG_VERSION").to_string(),
},
api_version: R::API_VERSION.to_string(),
bus_abi: BUS_ABI.id().to_string(),
required_contracts,
config_schema: serde_json::json!({}),
}
}
pub fn emit_apis_json<R: RuntimeBehavior>() -> String {
serde_json::to_string_pretty(&runtime_metadata::<R>())
.expect("RuntimeMetadata is always serializable")
}
pub fn print_emit_apis<R: RuntimeBehavior>() {
println!("{}", emit_apis_json::<R>());
}