1#[derive(
9 Debug,
10 Clone,
11 PartialEq,
12 Eq,
13 serde::Serialize,
14 serde::Deserialize,
15 rkyv::Archive,
16 rkyv::Serialize,
17 rkyv::Deserialize,
18 zerompk::ToMessagePack,
19 zerompk::FromMessagePack,
20)]
21pub struct LogEntry {
22 pub term: u64,
24 pub index: u64,
26 pub data: Vec<u8>,
29}
30
31#[derive(
36 Debug,
37 Clone,
38 serde::Serialize,
39 serde::Deserialize,
40 rkyv::Archive,
41 rkyv::Serialize,
42 rkyv::Deserialize,
43 zerompk::ToMessagePack,
44 zerompk::FromMessagePack,
45)]
46pub struct AppendEntriesRequest {
47 pub term: u64,
49 pub leader_id: u64,
51 pub prev_log_index: u64,
53 pub prev_log_term: u64,
55 pub entries: Vec<LogEntry>,
57 pub leader_commit: u64,
59 pub group_id: u64,
61}
62
63#[derive(
64 Debug,
65 Clone,
66 serde::Serialize,
67 serde::Deserialize,
68 rkyv::Archive,
69 rkyv::Serialize,
70 rkyv::Deserialize,
71 zerompk::ToMessagePack,
72 zerompk::FromMessagePack,
73)]
74pub struct AppendEntriesResponse {
75 pub term: u64,
77 pub success: bool,
79 pub last_log_index: u64,
82}
83
84#[derive(
86 Debug,
87 Clone,
88 serde::Serialize,
89 serde::Deserialize,
90 rkyv::Archive,
91 rkyv::Serialize,
92 rkyv::Deserialize,
93 zerompk::ToMessagePack,
94 zerompk::FromMessagePack,
95)]
96pub struct RequestVoteRequest {
97 pub term: u64,
99 pub candidate_id: u64,
101 pub last_log_index: u64,
103 pub last_log_term: u64,
105 pub group_id: u64,
107}
108
109#[derive(
110 Debug,
111 Clone,
112 serde::Serialize,
113 serde::Deserialize,
114 rkyv::Archive,
115 rkyv::Serialize,
116 rkyv::Deserialize,
117 zerompk::ToMessagePack,
118 zerompk::FromMessagePack,
119)]
120pub struct RequestVoteResponse {
121 pub term: u64,
123 pub vote_granted: bool,
125}
126
127#[derive(
131 Debug,
132 Clone,
133 serde::Serialize,
134 serde::Deserialize,
135 rkyv::Archive,
136 rkyv::Serialize,
137 rkyv::Deserialize,
138 zerompk::ToMessagePack,
139 zerompk::FromMessagePack,
140)]
141#[msgpack(map)]
142pub struct InstallSnapshotRequest {
143 pub term: u64,
145 pub leader_id: u64,
147 pub last_included_index: u64,
149 pub last_included_term: u64,
151 pub offset: u64,
153 pub data: Vec<u8>,
155 pub done: bool,
157 pub group_id: u64,
159 #[serde(default)]
163 #[msgpack(default)]
164 pub total_size: u64,
165}
166
167#[derive(
168 Debug,
169 Clone,
170 serde::Serialize,
171 serde::Deserialize,
172 rkyv::Archive,
173 rkyv::Serialize,
174 rkyv::Deserialize,
175 zerompk::ToMessagePack,
176 zerompk::FromMessagePack,
177)]
178pub struct InstallSnapshotResponse {
179 pub term: u64,
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 #[test]
188 fn log_entry_serde_roundtrip() {
189 let entry = LogEntry {
190 term: 5,
191 index: 42,
192 data: b"put key=val".to_vec(),
193 };
194 let json = sonic_rs::to_string(&entry).unwrap();
195 let decoded: LogEntry = sonic_rs::from_str(&json).unwrap();
196 assert_eq!(entry, decoded);
197 }
198
199 #[test]
200 fn append_entries_heartbeat() {
201 let req = AppendEntriesRequest {
202 term: 3,
203 leader_id: 1,
204 prev_log_index: 10,
205 prev_log_term: 2,
206 entries: vec![],
207 leader_commit: 8,
208 group_id: 0,
209 };
210 assert!(req.entries.is_empty());
211 }
212
213 #[test]
214 fn request_vote_serde_roundtrip() {
215 let req = RequestVoteRequest {
216 term: 7,
217 candidate_id: 2,
218 last_log_index: 100,
219 last_log_term: 6,
220 group_id: 5,
221 };
222 let json = sonic_rs::to_string(&req).unwrap();
223 let decoded: RequestVoteRequest = sonic_rs::from_str(&json).unwrap();
224 assert_eq!(req.term, decoded.term);
225 assert_eq!(req.candidate_id, decoded.candidate_id);
226 }
227}