libgrite_ipc/
discovery.rs1use rkyv::{Archive, Deserialize, Serialize};
6
7use crate::{IPC_SCHEMA_VERSION, PROTOCOL_NAME};
8
9#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
11#[rkyv(derive(Debug))]
12pub struct DiscoverRequest {
13 pub protocol: String,
15 pub min_version: u32,
17}
18
19impl DiscoverRequest {
20 pub fn new() -> Self {
22 Self {
23 protocol: PROTOCOL_NAME.to_string(),
24 min_version: 1,
25 }
26 }
27
28 pub fn with_min_version(min_version: u32) -> Self {
30 Self {
31 protocol: PROTOCOL_NAME.to_string(),
32 min_version,
33 }
34 }
35}
36
37impl Default for DiscoverRequest {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
45#[rkyv(derive(Debug))]
46pub struct DiscoverResponse {
47 pub protocol: String,
49 pub ipc_schema_version: u32,
51 pub daemon_id: String,
53 pub endpoint: String,
55 pub workers: Vec<WorkerInfo>,
57}
58
59impl DiscoverResponse {
60 pub fn new(daemon_id: String, endpoint: String, workers: Vec<WorkerInfo>) -> Self {
62 Self {
63 protocol: PROTOCOL_NAME.to_string(),
64 ipc_schema_version: IPC_SCHEMA_VERSION,
65 daemon_id,
66 endpoint,
67 workers,
68 }
69 }
70
71 pub fn has_worker(&self, repo_root: &str, actor_id: &str) -> bool {
73 self.workers
74 .iter()
75 .any(|w| w.repo_root == repo_root && w.actor_id == actor_id)
76 }
77}
78
79#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
81#[rkyv(derive(Debug))]
82pub struct WorkerInfo {
83 pub repo_root: String,
85 pub actor_id: String,
87 pub data_dir: String,
89}
90
91impl WorkerInfo {
92 pub fn new(repo_root: String, actor_id: String, data_dir: String) -> Self {
94 Self {
95 repo_root,
96 actor_id,
97 data_dir,
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_discover_request() {
108 let req = DiscoverRequest::new();
109 assert_eq!(req.protocol, PROTOCOL_NAME);
110 assert_eq!(req.min_version, 1);
111 }
112
113 #[test]
114 fn test_discover_response() {
115 let workers = vec![
116 WorkerInfo::new(
117 "/repo1".to_string(),
118 "actor1".to_string(),
119 "/repo1/.git/grite/actors/actor1".to_string(),
120 ),
121 WorkerInfo::new(
122 "/repo2".to_string(),
123 "actor2".to_string(),
124 "/repo2/.git/grite/actors/actor2".to_string(),
125 ),
126 ];
127
128 let resp = DiscoverResponse::new(
129 "daemon-123".to_string(),
130 "ipc:///tmp/grite-daemon.sock".to_string(),
131 workers,
132 );
133
134 assert!(resp.has_worker("/repo1", "actor1"));
135 assert!(resp.has_worker("/repo2", "actor2"));
136 assert!(!resp.has_worker("/repo3", "actor3"));
137 }
138
139 #[test]
140 fn test_rkyv_roundtrip() {
141 let req = DiscoverRequest::new();
142 let bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&req).unwrap();
143 let archived =
144 rkyv::access::<ArchivedDiscoverRequest, rkyv::rancor::Error>(&bytes).unwrap();
145 assert_eq!(archived.protocol.as_str(), PROTOCOL_NAME);
146 }
147}