use anyhow::Context;
use base64::prelude::*;
use nitro_shared::output::{Message, MessageLevel};
use serde::{Deserialize, Serialize};
pub static STARTING_DELIMITER: &str = "%_";
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum OutputAction {
Text(String, MessageLevel),
Message(Message),
StartProcess,
EndProcess,
StartSection,
EndSection,
SetResult(serde_json::Value),
SetError(String),
SetState(serde_json::Value),
SetCommandResult(CommandResult),
RunWorkerCommand {
command: String,
payload: serde_json::Value,
},
}
impl OutputAction {
pub fn serialize(&self, use_base64: bool, protocol_version: u16) -> anyhow::Result<String> {
let json = serde_json::to_string(&self).context("Failed to serialize output action")?;
let out = if use_base64 {
BASE64_STANDARD.encode(json)
} else {
json
};
if protocol_version >= 2 {
Ok(format!("{STARTING_DELIMITER}{out}"))
} else {
Ok(out)
}
}
pub fn deserialize(
action: &str,
use_base64: bool,
protocol_version: u16,
) -> anyhow::Result<Option<Self>> {
let action = if protocol_version >= 2 {
if let Some(stripped) = action.strip_prefix(STARTING_DELIMITER) {
stripped
} else {
return Ok(None);
}
} else {
action
};
let mut buf = Vec::new();
let json = if use_base64 {
BASE64_STANDARD
.decode_vec(action, &mut buf)
.context("Failed to decode action base64")?;
&mut buf
} else {
action.as_bytes()
};
let action = serde_json::from_slice(json).context("Failed to deserialize output action")?;
Ok(Some(action))
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum InputAction {
Command {
command: String,
payload: serde_json::Value,
},
CommandResult(CommandResult),
Terminate,
}
impl InputAction {
pub fn serialize(&self, protocol_version: u16) -> anyhow::Result<String> {
let _ = protocol_version;
serde_json::to_string(&self).context("Failed to serialize input action")
}
pub fn deserialize(action: &str, protocol_version: u16) -> anyhow::Result<Self> {
let _ = protocol_version;
serde_json::from_str(action).context("Failed to deserialize input action")
}
}
#[derive(Serialize, Deserialize)]
pub struct CommandResult {
command: String,
result: serde_json::Value,
}