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