use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use crate::error::KanbusError;
pub const PROTOCOL_VERSION: &str = "1.0";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RequestEnvelope {
pub protocol_version: String,
pub request_id: String,
pub action: String,
pub payload: BTreeMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorEnvelope {
pub code: String,
pub message: String,
pub details: BTreeMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResponseEnvelope {
pub protocol_version: String,
pub request_id: String,
pub status: String,
pub result: Option<BTreeMap<String, serde_json::Value>>,
pub error: Option<ErrorEnvelope>,
}
pub fn validate_protocol_compatibility(
client_version: &str,
daemon_version: &str,
) -> Result<(), KanbusError> {
let (client_major, client_minor) = parse_version(client_version)?;
let (daemon_major, daemon_minor) = parse_version(daemon_version)?;
if client_major != daemon_major {
return Err(KanbusError::ProtocolError(
"protocol version mismatch".to_string(),
));
}
if client_minor > daemon_minor {
return Err(KanbusError::ProtocolError(
"protocol version unsupported".to_string(),
));
}
Ok(())
}
fn parse_version(version: &str) -> Result<(u32, u32), KanbusError> {
let mut parts = version.split('.');
let major = parts
.next()
.ok_or_else(|| KanbusError::ProtocolError("invalid protocol version".to_string()))?;
let minor = parts
.next()
.ok_or_else(|| KanbusError::ProtocolError("invalid protocol version".to_string()))?;
if parts.next().is_some() {
return Err(KanbusError::ProtocolError(
"invalid protocol version".to_string(),
));
}
let major: u32 = major
.parse()
.map_err(|_| KanbusError::ProtocolError("invalid protocol version".to_string()))?;
let minor: u32 = minor
.parse()
.map_err(|_| KanbusError::ProtocolError("invalid protocol version".to_string()))?;
Ok((major, minor))
}