1use wowlab_types::sim::FastMap;
2
3#[derive(Clone, Debug, Default)]
5pub struct ClientInfo {
6 pub user: String,
7 pub client: String,
8 pub conn_info: Vec<u8>,
9 pub chan_info: Vec<u8>,
10}
11
12impl From<crate::proto::ClientInfo> for ClientInfo {
13 fn from(info: crate::proto::ClientInfo) -> Self {
14 Self {
15 user: info.user,
16 client: info.client,
17 conn_info: info.conn_info,
18 chan_info: info.chan_info,
19 }
20 }
21}
22
23#[derive(Clone, Debug)]
25pub struct Publication {
26 pub data: Vec<u8>,
27 pub info: Option<ClientInfo>,
28 pub offset: u64,
29 pub tags: FastMap<String, String>,
30 pub delta: bool,
31 pub time: i64,
32 pub channel: Option<String>,
33}
34
35impl From<crate::proto::Publication> for Publication {
36 fn from(pub_: crate::proto::Publication) -> Self {
37 Self {
38 data: pub_.data,
39 info: pub_.info.map(ClientInfo::from),
40 offset: pub_.offset,
41 tags: pub_.tags.into_iter().collect(),
42 delta: pub_.delta,
43 time: pub_.time,
44 channel: if pub_.channel.is_empty() {
45 None
46 } else {
47 Some(pub_.channel)
48 },
49 }
50 }
51}
52
53#[derive(Clone, Debug, Default)]
55pub struct StreamPosition {
56 pub offset: u64,
57 pub epoch: String,
58}
59
60impl From<crate::proto::StreamPosition> for StreamPosition {
61 fn from(pos: crate::proto::StreamPosition) -> Self {
62 Self {
63 offset: pos.offset,
64 epoch: pos.epoch,
65 }
66 }
67}
68
69#[derive(Clone, Debug)]
71pub struct ConnectResult {
72 pub client: String,
73 pub version: String,
74 pub expires: bool,
75 pub ttl: u32,
76 pub data: Vec<u8>,
77 pub ping: u32,
79 pub pong: bool,
80 pub session: String,
81 pub node: String,
82 pub time: i64,
83}
84
85impl From<crate::proto::ConnectResult> for ConnectResult {
86 fn from(result: crate::proto::ConnectResult) -> Self {
87 Self {
88 client: result.client,
89 version: result.version,
90 expires: result.expires,
91 ttl: result.ttl,
92 data: result.data,
93 ping: result.ping,
94 pong: result.pong,
95 session: result.session,
96 node: result.node,
97 time: result.time,
98 }
99 }
100}
101
102#[derive(Clone, Debug)]
104#[expect(
105 clippy::struct_excessive_bools,
106 reason = "mirrors Centrifugo's public subscribe result protocol"
107)]
108pub struct SubscribeResult {
109 pub expires: bool,
110 pub ttl: u32,
111 pub recoverable: bool,
112 pub epoch: String,
113 pub publications: Vec<Publication>,
114 pub recovered: bool,
115 pub offset: u64,
116 pub positioned: bool,
117 pub data: Vec<u8>,
118 pub was_recovering: bool,
119 pub delta: bool,
120}
121
122impl From<crate::proto::SubscribeResult> for SubscribeResult {
123 fn from(result: crate::proto::SubscribeResult) -> Self {
124 Self {
125 expires: result.expires,
126 ttl: result.ttl,
127 recoverable: result.recoverable,
128 epoch: result.epoch,
129 publications: result
130 .publications
131 .into_iter()
132 .map(Publication::from)
133 .collect(),
134 recovered: result.recovered,
135 offset: result.offset,
136 positioned: result.positioned,
137 data: result.data,
138 was_recovering: result.was_recovering,
139 delta: result.delta,
140 }
141 }
142}
143
144#[derive(Clone, Debug)]
146#[non_exhaustive]
147pub enum ClientEvent {
148 Connecting,
149 Connected(ConnectResult),
150 Disconnected {
151 code: u32,
152 reason: String,
153 reconnect: bool,
154 },
155 Error(String),
156 Message(Vec<u8>),
157}
158
159#[derive(Clone, Debug)]
161#[non_exhaustive]
162pub enum SubscriptionEvent {
163 Subscribing,
164 Subscribed(SubscribeResult),
165 Unsubscribed { code: u32, reason: String },
166 Publication(Publication),
167 Join(ClientInfo),
168 Leave(ClientInfo),
169 Error(String),
170}
171
172#[derive(Clone, Debug, Default)]
174pub struct PresenceResult {
175 pub presence: FastMap<String, ClientInfo>,
176}
177
178impl From<crate::proto::PresenceResult> for PresenceResult {
179 fn from(result: crate::proto::PresenceResult) -> Self {
180 Self {
181 presence: result
182 .presence
183 .into_iter()
184 .map(|(k, v)| (k, ClientInfo::from(v)))
185 .collect(),
186 }
187 }
188}
189
190#[derive(Clone, Debug, Default)]
192pub struct PresenceStats {
193 pub num_clients: u32,
194 pub num_users: u32,
195}
196
197impl From<crate::proto::PresenceStatsResult> for PresenceStats {
198 fn from(result: crate::proto::PresenceStatsResult) -> Self {
199 Self {
200 num_clients: result.num_clients,
201 num_users: result.num_users,
202 }
203 }
204}
205
206#[derive(Clone, Debug, Default)]
208pub struct HistoryResult {
209 pub publications: Vec<Publication>,
210 pub epoch: String,
211 pub offset: u64,
212}
213
214impl From<crate::proto::HistoryResult> for HistoryResult {
215 fn from(result: crate::proto::HistoryResult) -> Self {
216 Self {
217 publications: result
218 .publications
219 .into_iter()
220 .map(Publication::from)
221 .collect(),
222 epoch: result.epoch,
223 offset: result.offset,
224 }
225 }
226}
227
228#[derive(Clone, Debug, Default)]
230pub struct RpcResult {
231 pub data: Vec<u8>,
232}
233
234impl From<crate::proto::RpcResult> for RpcResult {
235 fn from(result: crate::proto::RpcResult) -> Self {
236 Self { data: result.data }
237 }
238}
239
240#[derive(Clone, Debug, Default)]
242pub struct SubRefreshResult {
243 pub expires: bool,
244 pub ttl: u32,
245}
246
247impl From<crate::proto::SubRefreshResult> for SubRefreshResult {
248 fn from(result: crate::proto::SubRefreshResult) -> Self {
249 Self {
250 expires: result.expires,
251 ttl: result.ttl,
252 }
253 }
254}