1use protosocket_rpc::{Message, ProtosocketControlCode};
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
17pub enum WireFieldValue {
18 U64(u64),
19 I64(i64),
20 F64(f64),
21 Bool(bool),
22 Str(String),
23}
24
25impl WireFieldValue {
26 pub fn to_string_value(&self) -> String {
28 match self {
29 WireFieldValue::U64(v) => v.to_string(),
30 WireFieldValue::I64(v) => v.to_string(),
31 WireFieldValue::F64(v) => v.to_string(),
32 WireFieldValue::Bool(v) => v.to_string(),
33 WireFieldValue::Str(s) => s.clone(),
34 }
35 }
36
37 pub fn contains(&self, needle: &str) -> bool {
39 match self {
40 WireFieldValue::Str(s) => s.contains(needle),
41 other => other.to_string_value().contains(needle),
42 }
43 }
44}
45
46impl std::fmt::Display for WireFieldValue {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 match self {
49 WireFieldValue::U64(v) => write!(f, "{v}"),
50 WireFieldValue::I64(v) => write!(f, "{v}"),
51 WireFieldValue::F64(v) => write!(f, "{v}"),
52 WireFieldValue::Bool(v) => write!(f, "{v}"),
53 WireFieldValue::Str(s) => f.write_str(s),
54 }
55 }
56}
57
58#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
61pub enum WireLevel {
62 Trace,
63 Debug,
64 Info,
65 Warn,
66 Error,
67}
68
69impl WireLevel {
70 pub fn from_tracing(level: &tracing::Level) -> Self {
71 match *level {
73 tracing::Level::TRACE => WireLevel::Trace,
74 tracing::Level::DEBUG => WireLevel::Debug,
75 tracing::Level::INFO => WireLevel::Info,
76 tracing::Level::WARN => WireLevel::Warn,
77 tracing::Level::ERROR => WireLevel::Error,
78 }
79 }
80
81 pub fn to_tracing(self) -> tracing::Level {
82 match self {
83 WireLevel::Trace => tracing::Level::TRACE,
84 WireLevel::Debug => tracing::Level::DEBUG,
85 WireLevel::Info => tracing::Level::INFO,
86 WireLevel::Warn => tracing::Level::WARN,
87 WireLevel::Error => tracing::Level::ERROR,
88 }
89 }
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct WireEvent {
94 pub name: String,
95 pub level: WireLevel,
96 pub fields: Vec<(String, WireFieldValue)>,
97 pub recorded_at_ns: u64,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct WireSpan {
103 pub id: u64,
104 pub parent_id: Option<u64>,
105 pub name: String,
106 pub target: String,
107 pub level: WireLevel,
108 pub fields: Vec<(String, WireFieldValue)>,
109 pub events: Vec<WireEvent>,
110 pub opened_at_ns: u64,
112 pub closed_at_ns: Option<u64>,
115}
116
117impl WireSpan {
118 pub fn field(&self, name: &str) -> Option<&WireFieldValue> {
120 self.fields.iter().find(|(k, _)| k == name).map(|(_, v)| v)
121 }
122}
123
124impl WireEvent {
125 pub fn field(&self, name: &str) -> Option<&WireFieldValue> {
126 self.fields.iter().find(|(k, _)| k == name).map(|(_, v)| v)
127 }
128}
129
130#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
137pub enum WireLevelFilter {
138 Off,
139 Error,
140 Warn,
141 Info,
142 Debug,
143 Trace,
144}
145
146impl WireLevelFilter {
147 pub fn from_tracing(filter: tracing::metadata::LevelFilter) -> Self {
148 use tracing::metadata::LevelFilter as L;
149 if filter == L::OFF {
150 WireLevelFilter::Off
151 } else if filter == L::ERROR {
152 WireLevelFilter::Error
153 } else if filter == L::WARN {
154 WireLevelFilter::Warn
155 } else if filter == L::INFO {
156 WireLevelFilter::Info
157 } else if filter == L::DEBUG {
158 WireLevelFilter::Debug
159 } else {
160 WireLevelFilter::Trace
161 }
162 }
163
164 pub fn to_tracing(self) -> tracing::metadata::LevelFilter {
165 use tracing::metadata::LevelFilter as L;
166 match self {
167 WireLevelFilter::Off => L::OFF,
168 WireLevelFilter::Error => L::ERROR,
169 WireLevelFilter::Warn => L::WARN,
170 WireLevelFilter::Info => L::INFO,
171 WireLevelFilter::Debug => L::DEBUG,
172 WireLevelFilter::Trace => L::TRACE,
173 }
174 }
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
180pub enum RequestBody {
181 Noop,
183 StartStream,
186 StopStream,
190 SetLevel(WireLevel),
193 SetCacheLevel(WireLevelFilter),
199 SetCacheChance(f64),
204 SetSamplingRate(f64),
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct Request {
211 pub id: u64,
212 pub control: u8,
213 pub body: RequestBody,
214}
215
216impl Request {
217 pub fn new(body: RequestBody) -> Self {
218 Self {
219 id: 0,
220 control: ProtosocketControlCode::Normal.as_u8(),
221 body,
222 }
223 }
224}
225
226impl Message for Request {
227 fn message_id(&self) -> u64 {
228 self.id
229 }
230 fn control_code(&self) -> ProtosocketControlCode {
231 ProtosocketControlCode::from_u8(self.control)
232 }
233 fn set_message_id(&mut self, id: u64) {
234 self.id = id
235 }
236 fn cancelled(id: u64) -> Self {
237 Self {
238 id,
239 control: ProtosocketControlCode::Cancel.as_u8(),
240 body: RequestBody::Noop,
241 }
242 }
243 fn ended(id: u64) -> Self {
244 Self {
245 id,
246 control: ProtosocketControlCode::End.as_u8(),
247 body: RequestBody::Noop,
248 }
249 }
250}
251
252#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
262pub struct WireServerInfo {
263 pub version: String,
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize)]
269pub enum ResponseBody {
270 Noop,
272 ServerInfo(WireServerInfo),
275 Span(WireSpan),
278 CacheLevel(WireLevelFilter),
283 CacheChance(f64),
288 Ack,
290 Error(String),
292}
293
294#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct Response {
296 pub id: u64,
297 pub control: u8,
298 pub body: ResponseBody,
299}
300
301impl Response {
302 pub fn new(body: ResponseBody) -> Self {
303 Self {
304 id: 0,
305 control: ProtosocketControlCode::Normal.as_u8(),
306 body,
307 }
308 }
309 pub fn ack() -> Self {
310 Self::new(ResponseBody::Ack)
311 }
312 pub fn error(msg: impl Into<String>) -> Self {
313 Self::new(ResponseBody::Error(msg.into()))
314 }
315 pub fn span(s: WireSpan) -> Self {
316 Self::new(ResponseBody::Span(s))
317 }
318 pub fn cache_level(level: WireLevelFilter) -> Self {
319 Self::new(ResponseBody::CacheLevel(level))
320 }
321 pub fn cache_chance(pct: f64) -> Self {
322 Self::new(ResponseBody::CacheChance(pct))
323 }
324 pub fn server_info(version: impl Into<String>) -> Self {
325 Self::new(ResponseBody::ServerInfo(WireServerInfo {
326 version: version.into(),
327 }))
328 }
329 pub fn with_id(mut self, id: u64) -> Self {
337 self.id = id;
338 self
339 }
340}
341
342impl Message for Response {
343 fn message_id(&self) -> u64 {
344 self.id
345 }
346 fn control_code(&self) -> ProtosocketControlCode {
347 ProtosocketControlCode::from_u8(self.control)
348 }
349 fn set_message_id(&mut self, id: u64) {
350 self.id = id
351 }
352 fn cancelled(id: u64) -> Self {
353 Self {
354 id,
355 control: ProtosocketControlCode::Cancel.as_u8(),
356 body: ResponseBody::Noop,
357 }
358 }
359 fn ended(id: u64) -> Self {
360 Self {
361 id,
362 control: ProtosocketControlCode::End.as_u8(),
363 body: ResponseBody::Noop,
364 }
365 }
366}