use anyhow::{Context, Result};
use serde_json::json;
pub fn print(message: &str, output_opt: Option<&str>) -> Result<()> {
match output_opt {
Some("json") => {
let value = json!({"status": "ok", "message": message});
println!(
"{}",
serde_json::to_string(&value)
.context("Failed to serialize action result to JSON")?
);
}
_ => println!("{message}"),
}
Ok(())
}
pub fn print_with_data<T: serde::Serialize>(
message: &str,
data: &T,
output_opt: Option<&str>,
) -> Result<()> {
match output_opt {
Some("json") => {
let data_value = serde_json::to_value(data)
.context("Failed to convert data payload to JSON")?;
let value =
json!({"status": "ok", "message": message, "data": data_value});
println!(
"{}",
serde_json::to_string(&value)
.context("Failed to serialize action result to JSON")?
);
}
_ => {
println!("{message}");
println!(
"{}",
serde_json::to_string_pretty(data)
.context("Failed to pretty-print data payload")?
);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::Value;
fn json_of(message: &str) -> Value {
let v = json!({"status": "ok", "message": message});
serde_json::from_str(&serde_json::to_string(&v).unwrap()).unwrap()
}
#[test]
fn json_shape_for_plain_message() {
let v = json_of("Group 'foo' added");
assert_eq!(v["status"], "ok");
assert_eq!(v["message"], "Group 'foo' added");
}
#[test]
fn print_with_data_includes_payload() {
let payload = json!({"id": "x3000c0s1b0", "enabled": true});
let combined = json!({
"status": "ok",
"message": "endpoint added",
"data": payload,
});
assert_eq!(combined["data"]["id"], "x3000c0s1b0");
assert_eq!(combined["data"]["enabled"], true);
}
#[test]
fn print_text_mode_does_not_error() {
print("hello", None).unwrap();
print("hello", Some("table")).unwrap();
}
#[test]
fn print_json_mode_does_not_error() {
print("hello", Some("json")).unwrap();
}
}