use rkyv::{Archive, Deserialize, Serialize};
use crate::{IPC_SCHEMA_VERSION, PROTOCOL_NAME};
#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
#[rkyv(derive(Debug))]
pub struct DiscoverRequest {
pub protocol: String,
pub min_version: u32,
}
impl DiscoverRequest {
pub fn new() -> Self {
Self {
protocol: PROTOCOL_NAME.to_string(),
min_version: 1,
}
}
pub fn with_min_version(min_version: u32) -> Self {
Self {
protocol: PROTOCOL_NAME.to_string(),
min_version,
}
}
}
impl Default for DiscoverRequest {
fn default() -> Self {
Self::new()
}
}
#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
#[rkyv(derive(Debug))]
pub struct DiscoverResponse {
pub protocol: String,
pub ipc_schema_version: u32,
pub daemon_id: String,
pub endpoint: String,
pub workers: Vec<WorkerInfo>,
}
impl DiscoverResponse {
pub fn new(daemon_id: String, endpoint: String, workers: Vec<WorkerInfo>) -> Self {
Self {
protocol: PROTOCOL_NAME.to_string(),
ipc_schema_version: IPC_SCHEMA_VERSION,
daemon_id,
endpoint,
workers,
}
}
pub fn has_worker(&self, repo_root: &str, actor_id: &str) -> bool {
self.workers
.iter()
.any(|w| w.repo_root == repo_root && w.actor_id == actor_id)
}
}
#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
#[rkyv(derive(Debug))]
pub struct WorkerInfo {
pub repo_root: String,
pub actor_id: String,
pub data_dir: String,
}
impl WorkerInfo {
pub fn new(repo_root: String, actor_id: String, data_dir: String) -> Self {
Self {
repo_root,
actor_id,
data_dir,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_discover_request() {
let req = DiscoverRequest::new();
assert_eq!(req.protocol, PROTOCOL_NAME);
assert_eq!(req.min_version, 1);
}
#[test]
fn test_discover_response() {
let workers = vec![
WorkerInfo::new(
"/repo1".to_string(),
"actor1".to_string(),
"/repo1/.git/grite/actors/actor1".to_string(),
),
WorkerInfo::new(
"/repo2".to_string(),
"actor2".to_string(),
"/repo2/.git/grite/actors/actor2".to_string(),
),
];
let resp = DiscoverResponse::new(
"daemon-123".to_string(),
"ipc:///tmp/grite-daemon.sock".to_string(),
workers,
);
assert!(resp.has_worker("/repo1", "actor1"));
assert!(resp.has_worker("/repo2", "actor2"));
assert!(!resp.has_worker("/repo3", "actor3"));
}
#[test]
fn test_rkyv_roundtrip() {
let req = DiscoverRequest::new();
let bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&req).unwrap();
let archived =
rkyv::access::<ArchivedDiscoverRequest, rkyv::rancor::Error>(&bytes).unwrap();
assert_eq!(archived.protocol.as_str(), PROTOCOL_NAME);
}
}