backhopper_core/model/wire_envelope.rs
1// Copyright (C) 2026 Michael S. Klishin and Contributors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// See LICENSE-APACHE and LICENSE-MIT for details.
4
5//! The canonical JSON envelope frame every verb wraps its payload in.
6//!
7//! One definition the CLI serializes, the driver parses, and `schema
8//! show` documents, so the frame cannot drift across the three. The
9//! payload type `T` is the per-verb body.
10
11use serde::{Deserialize, Serialize};
12
13/// A non-fatal warning carried alongside a payload.
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
16pub struct EnvelopeWarning {
17 /// Stable warning code, kebab-case (e.g. `stale-extractor`).
18 pub code: String,
19 /// Human-readable message.
20 pub message: String,
21}
22
23/// The `{schema_version, command, data, exit_code[, warnings]}` frame.
24///
25/// `command` and `warnings` are lenient on the read side (an older
26/// producer may omit either); `warnings` is dropped from the wire when
27/// empty, matching the CLI, which does not emit it today.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
30pub struct WireEnvelope<T> {
31 pub schema_version: u32,
32 #[serde(default)]
33 pub command: Option<String>,
34 pub data: T,
35 #[serde(default)]
36 pub exit_code: i32,
37 #[serde(default, skip_serializing_if = "Vec::is_empty")]
38 pub warnings: Vec<EnvelopeWarning>,
39}