1use anyhow::Result;
2use serde::Serialize;
3use serde_json::Value;
4
5#[derive(Debug, Clone, Serialize)]
6pub struct ErrorEnvelope {
7 pub code: String,
8 pub message: String,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub details: Option<Value>,
11}
12
13#[derive(Debug, Clone, Serialize)]
14pub struct JsonEnvelopeResult<T: Serialize> {
15 pub schema_version: String,
16 pub command: String,
17 pub ok: bool,
18 pub result: T,
19}
20
21#[derive(Debug, Clone, Serialize)]
22pub struct JsonEnvelopeResults<T: Serialize> {
23 pub schema_version: String,
24 pub command: String,
25 pub ok: bool,
26 pub results: Vec<T>,
27}
28
29#[derive(Debug, Clone, Serialize)]
30pub struct JsonEnvelopeError {
31 pub schema_version: String,
32 pub command: String,
33 pub ok: bool,
34 pub error: ErrorEnvelope,
35}
36
37pub fn emit_json<T: Serialize>(payload: &T) -> Result<()> {
38 println!("{}", serde_json::to_string(payload)?);
39 Ok(())
40}
41
42pub fn emit_success_result<T: Serialize>(
43 schema_version: &str,
44 command: &str,
45 result: T,
46) -> Result<()> {
47 emit_json(&JsonEnvelopeResult {
48 schema_version: schema_version.to_string(),
49 command: command.to_string(),
50 ok: true,
51 result,
52 })
53}
54
55pub fn emit_success_results<T: Serialize>(
56 schema_version: &str,
57 command: &str,
58 results: Vec<T>,
59) -> Result<()> {
60 emit_json(&JsonEnvelopeResults {
61 schema_version: schema_version.to_string(),
62 command: command.to_string(),
63 ok: true,
64 results,
65 })
66}
67
68pub fn emit_error(
69 schema_version: &str,
70 command: &str,
71 code: &str,
72 message: impl Into<String>,
73 details: Option<Value>,
74) -> Result<()> {
75 emit_json(&JsonEnvelopeError {
76 schema_version: schema_version.to_string(),
77 command: command.to_string(),
78 ok: false,
79 error: ErrorEnvelope {
80 code: code.to_string(),
81 message: message.into(),
82 details,
83 },
84 })
85}