common/peer/jax_protocol/
messages.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4use crate::linked_data::Link;
5
6/// Top-level request enum for the JAX protocol
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub enum Request {
9    /// Ping request to check sync status
10    Ping(PingRequest),
11    /// Fetch bucket request to get current link
12    FetchBucket(FetchBucketRequest),
13    /// Announce message (one-way, no response expected)
14    Announce(AnnounceMessage),
15}
16
17/// Top-level response enum for the JAX protocol
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub enum Response {
20    /// Ping response with sync status
21    Ping(PingResponse),
22    /// Fetch bucket response with current link
23    FetchBucket(FetchBucketResponse),
24}
25
26/// Request to ping a peer and check bucket sync status
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct PingRequest {
29    /// The bucket ID to check
30    pub bucket_id: Uuid,
31    /// The current link the requesting peer has for this bucket
32    pub current_link: Link,
33}
34
35/// Sync status between two peers for a bucket
36#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
37pub enum SyncStatus {
38    /// The peer does not have this bucket
39    NotFound,
40    /// The requesting peer's link is in the responding peer's history (requesting peer is behind)
41    Behind,
42    /// Both peers have the same current link (in sync)
43    InSync,
44    /// The requesting peer's link is beyond the responding peer's history (responding peer is behind)
45    Ahead,
46}
47
48/// Response to a ping request
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct PingResponse {
51    pub status: SyncStatus,
52}
53
54impl PingResponse {
55    pub fn new(status: SyncStatus) -> Self {
56        Self { status }
57    }
58
59    pub fn not_found() -> Self {
60        Self {
61            status: SyncStatus::NotFound,
62        }
63    }
64
65    pub fn behind() -> Self {
66        Self {
67            status: SyncStatus::Behind,
68        }
69    }
70
71    pub fn in_sync() -> Self {
72        Self {
73            status: SyncStatus::InSync,
74        }
75    }
76
77    pub fn unsynced() -> Self {
78        Self {
79            status: SyncStatus::Ahead,
80        }
81    }
82}
83
84/// Announcement of a new bucket version to peers
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct AnnounceMessage {
87    /// The bucket ID being announced
88    pub bucket_id: Uuid,
89    /// The new link for this bucket
90    pub new_link: Link,
91    /// The previous link (for single-hop verification)
92    pub previous_link: Option<Link>,
93}
94
95impl AnnounceMessage {
96    pub fn new(bucket_id: Uuid, new_link: Link, previous_link: Option<Link>) -> Self {
97        Self {
98            bucket_id,
99            new_link,
100            previous_link,
101        }
102    }
103}
104
105/// Request to fetch the current bucket link from a peer
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct FetchBucketRequest {
108    /// The bucket ID to fetch
109    pub bucket_id: Uuid,
110}
111
112impl FetchBucketRequest {
113    pub fn new(bucket_id: Uuid) -> Self {
114        Self { bucket_id }
115    }
116}
117
118/// Response to a fetch bucket request
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct FetchBucketResponse {
121    /// The current link for this bucket (None if bucket not found)
122    pub current_link: Option<Link>,
123}
124
125impl FetchBucketResponse {
126    pub fn new(current_link: Option<Link>) -> Self {
127        Self { current_link }
128    }
129
130    pub fn not_found() -> Self {
131        Self { current_link: None }
132    }
133
134    pub fn found(link: Link) -> Self {
135        Self {
136            current_link: Some(link),
137        }
138    }
139}