use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "payload")]
pub enum AppMessage {
Pair {
token: String,
device_name: String,
device_os: String,
},
Ping { seq: u64 },
SyncEnv {
project: String,
environment: String,
vars: Vec<EnvVar>,
},
DeleteEnv {
project: String,
environment: String,
},
SyncBlocklist {
platforms: Vec<BlockedPlatform>,
},
SyncVault {
entries: Vec<VaultEntry>,
},
RequestSync { resource: String },
TriggerReload { target: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "payload")]
pub enum DaemonMessage {
PairOk {
daemon_name: String,
daemon_version: String,
fingerprint: String,
},
PairReject { reason: String },
Error { code: String, message: String },
Pong { seq: u64, ts: i64 },
Ok { for_type: String },
Metrics(SystemMetrics),
Reloading { target: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvVar {
pub key: String,
pub value: String,
#[serde(rename = "type")]
pub var_type: String,
pub secret: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BlockedPlatform {
pub id: String,
pub name: String,
pub domains: Vec<String>,
pub enabled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VaultEntry {
pub id: u64,
pub service: String,
pub username: String,
pub encrypted_password: String,
pub category: String,
pub url: String,
pub notes: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemMetrics {
pub cpu_percent: f32,
pub ram_used_gb: f32,
pub ram_total_gb: f32,
pub uptime_secs: u64,
pub timestamp: i64,
}
pub struct Framer;
impl Framer {
pub fn encode(msg: &DaemonMessage) -> anyhow::Result<Vec<u8>> {
let json = serde_json::to_vec(msg)?;
let len = json.len() as u32;
let mut buf = Vec::with_capacity(4 + json.len());
buf.extend_from_slice(&len.to_be_bytes());
buf.extend_from_slice(&json);
Ok(buf)
}
pub fn decode_app(data: &[u8]) -> anyhow::Result<AppMessage> {
Ok(serde_json::from_slice(data)?)
}
}