use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub trait Envelopable: Serialize {
fn to_toml_payload(&self) -> Result<String, String> {
toml::to_string(self).map_err(|e| format!("TOML_SERIALIZATION_ERROR: {}", e))
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Envelope {
pub persona: String,
pub metadata: HashMap<String, String>,
pub payload: String,
}
impl Envelope {
pub fn new(persona: &str, payload: String) -> Self {
Self {
persona: persona.to_string(),
metadata: HashMap::new(),
payload,
}
}
pub fn pack<T: Envelopable>(persona: &str, data: &T) -> Result<String, String> {
let toml_content = data.to_toml_payload()?;
let envelope = Self::new(persona, toml_content);
serde_json::to_string(&envelope).map_err(|e| format!("IPC_PACKING_ERROR: {}", e))
}
pub fn unpack(json_input: &str) -> Result<Self, String> {
serde_json::from_str(json_input).map_err(|e| format!("IPC_UNPACKING_ERROR: {}", e))
}
}
impl Envelope {
pub fn to_oracle_prompt(&self) -> String {
format!(
"--- START ENGRAM [{}] ---\n{}\n--- END ENGRAM ---",
self.persona.to_uppercase(),
self.payload
)
}
pub fn json_to_toml(persona: &str, json_input: &str) -> Result<Self, String> {
let json_value: serde_json::Value = serde_json::from_str(json_input)
.map_err(|e| format!("INCOMING_JSON_INVALID: {}", e))?;
let toml_payload = toml::to_string(&json_value)
.map_err(|e| format!("TOML_CONVERSION_FAILED: {}", e))?;
Ok(Self::new(persona, toml_payload))
}
pub fn toml_to_json(&self) -> Result<String, String> {
let toml_value: toml::Value = toml::from_str(&self.payload)
.map_err(|e| format!("ORACLE_TOML_INVALID: {}", e))?;
serde_json::to_string(&toml_value)
.map_err(|e| format!("JSON_RECONSTRUCTION_FAILED: {}", e))?
.to_string()
.pipe_ok() }
}
trait PipeOk { fn pipe_ok(self) -> Result<Self, String> where Self: Sized; }
impl PipeOk for String { fn pipe_ok(self) -> Result<Self, String> { Ok(self) } }