heddle_core/contract.rs
1// SPDX-License-Identifier: Apache-2.0
2//! Typed machine-output contracts for embeddable Heddle reports.
3
4use schemars::JsonSchema;
5use serde::Serialize;
6use serde_json::Value;
7
8/// Stable contract metadata carried beside a typed Heddle report.
9#[derive(Debug, Clone, Copy)]
10pub struct ReportContract {
11 /// Stable schema identifier for this report shape.
12 pub schema_name: &'static str,
13 /// Machine-readable stream/container kind emitted for this report.
14 pub machine_output_kind: MachineOutputKind,
15 /// Stable output discriminator emitted in the report payload, when the
16 /// report shape has one. Legacy discriminator-less reports keep this absent
17 /// so the contract does not force a JSON shape change.
18 pub output_discriminator: Option<OutputDiscriminator>,
19 /// Generate the JSON Schema for this report shape.
20 pub schema: fn() -> Value,
21}
22
23/// A stable field/value discriminator in a machine-readable report payload.
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct OutputDiscriminator {
26 pub field: &'static str,
27 pub value: &'static str,
28}
29
30/// The machine-readable output container a report is serialized into.
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum MachineOutputKind {
33 /// A single JSON object.
34 Json,
35 /// Newline-delimited JSON records.
36 JsonLines,
37 /// Either a single JSON object or newline-delimited JSON records.
38 JsonOrJsonLines,
39}
40
41/// A typed report that exposes its stable machine-output contract.
42pub trait HeddleReport: Serialize + JsonSchema {
43 const CONTRACT: ReportContract;
44}
45
46/// Generate a JSON Schema value for a report type.
47pub fn schema_for_report<T>() -> Value
48where
49 T: JsonSchema,
50{
51 serde_json::to_value(schemars::schema_for!(T))
52 .unwrap_or_else(|_| serde_json::json!({ "type": "object" }))
53}