1use rustc_version::version_meta;
2use serde::{Deserialize, Serialize};
3
4mod message;
5use message::*;
6
7#[cfg(test)]
8mod tests;
9
10#[macro_export]
11macro_rules! ray {
12 () => {{
14 let ray = Ray::new();
15
16 ray
17 }};
18 ($($arg:expr),*) => {{
20 let mut ray = Ray::new();
21 let mut vec = Vec::new();
22
23 $(vec.push(format!("{:#?}", $arg));)*
25
26 ray.log(vec);
27
28 ray
29 }};
30}
31
32#[macro_export]
33macro_rules! rd {
34 () => {{
35 let mut ray = Ray::new();
36
37 ray.die(1);
38
39 ray
40 }};
41 ($($arg:expr),*) => {{
42 let mut ray = Ray::new();
43 let mut vec = Vec::new();
44
45 $(vec.push(format!("{:#?}", $arg));)*
46
47 ray.log(vec);
48
49 ray.die(1);
50
51 ray
52 }};
53}
54
55#[derive(Debug, Serialize, Deserialize, Clone)]
56pub struct RayPayload {
57 uuid: String,
58 payloads: Vec<RayContent>,
59 meta: RayMeta,
60}
61
62#[derive(Debug, Serialize, Deserialize, Clone)]
63pub struct RayContent {
64 #[serde(rename = "type")] content_type: String,
66 content: RayMessage,
67 origin: RayOrigin,
68}
69
70#[derive(Debug, Serialize, Deserialize, Clone)]
71pub struct RayOrigin {
72 function_name: String,
73 file: String,
74 line_number: u32,
75 hostname: String,
76}
77
78impl RayOrigin {
79 pub fn new() -> Self {
80 let function_name = "ray".to_string();
84 let file = "".to_string();
85 let line_number = 0;
86 let hostname = "localhost".to_string();
87
88 Self {
89 function_name,
90 file,
91 line_number,
92 hostname,
93 }
94 }
95}
96
97#[derive(Debug, Serialize, Deserialize, Clone)]
98pub struct RayMeta {
99 rustc_version: String,
102 package_version: String,
103}
104
105impl RayMeta {
106 pub fn new() -> Self {
107 let rustc_version = match version_meta() {
108 Ok(meta) => meta.short_version_string,
109 Err(_) => "🤷".to_string(),
110 };
111
112 Self {
113 rustc_version,
114 package_version: env!("CARGO_PKG_VERSION").to_string(),
115 }
116 }
117}
118
119pub struct Ray {
120 request: RayPayload,
121 is_enabled: bool,
122}
123
124impl Ray {
125 pub fn new() -> Self {
126 Self {
127 request: RayPayload {
128 uuid: uuid::Uuid::new_v4().to_string(),
129 payloads: vec![],
130 meta: RayMeta::new(),
131 },
132 is_enabled: true,
133 }
134 }
135
136 #[cfg(feature = "with_tokio")]
137 pub fn send(&mut self) {
138 if !self.is_enabled {
139 return ();
140 }
141
142 let request = self.request.clone();
143
144 let _ = tokio::task::spawn_blocking(move || {
145 let client = reqwest::blocking::Client::new();
146
147 let _ = client.post("http://localhost:23517").json(&request).send();
148 });
149 }
150
151 #[cfg(not(feature = "with_tokio"))]
152 pub fn send(&mut self) {
153 if !self.is_enabled {
154 return ();
155 }
156
157 let request = self.request.clone();
158
159 let client = reqwest::blocking::Client::new();
160
161 let _ = client.post("http://localhost:23517").json(&request).send();
162 }
163
164 pub fn die(&mut self, status: i32) {
165 panic!("exited with code {}", status);
166
167 }
171
172 pub fn clear_all(&mut self) -> &mut Self {
173 let message = RayMessage::ClearAll(RayClearAll {
174 label: RayMessageType::ClearAll,
175 });
176
177 let content = RayContent {
178 content_type: RayClearAll::get_type(),
179 origin: RayOrigin::new(),
180 content: message,
181 };
182
183 self.request.payloads.push(content);
184
185 self.send();
186 self
187 }
188
189 pub fn new_screen(&mut self, name: Option<&str>) -> &mut Self {
190 let message = RayMessage::NewScreen(RayNewScreen {
191 label: RayMessageType::NewScreen,
192 name: name.unwrap_or("").to_string(),
193 });
194
195 let content = RayContent {
196 content_type: RayNewScreen::get_type(),
197 origin: RayOrigin::new(),
198 content: message,
199 };
200
201 self.request.payloads.push(content);
202
203 self.send();
204 self
205 }
206
207 pub fn clear_screen(&mut self) -> &mut Self {
208 self.new_screen(None)
209 }
210
211 pub fn log(&mut self, values: Vec<String>) -> &mut Self {
212 let message = RayMessage::Log(RayLog {
213 label: RayMessageType::Log,
214 values,
215 });
216
217 let content = RayContent {
218 content_type: RayLog::get_type(),
219 origin: RayOrigin::new(),
220 content: message,
221 };
222
223 self.request.payloads.push(content);
224
225 self.send();
226 self
227 }
228
229 pub fn text(&mut self, value: &str) -> &mut Self {
230 let message = RayMessage::Text(RayText {
231 label: RayMessageType::Text,
232 content: value.to_string(),
233 });
234
235 let content = RayContent {
236 content_type: RayText::get_type(),
237 origin: RayOrigin::new(),
238 content: message,
239 };
240
241 self.request.payloads.push(content);
242
243 self.send();
244 self
245 }
246
247 pub fn color(&mut self, value: &str) -> &mut Self {
248 let message = RayMessage::Color(RayColor {
249 color: RayColors::from(value.to_string()),
250 });
251
252 let content = RayContent {
253 content_type: RayColor::get_type(),
254 origin: RayOrigin::new(),
255 content: message,
256 };
257
258 self.request.payloads.push(content);
259
260 self.send();
261 self
262 }
263
264 pub fn html(&mut self, value: &str) -> &mut Self {
265 let message = RayMessage::HTML(RayHtml {
266 label: RayMessageType::HTML,
267 content: value.to_string(),
268 });
269
270 let content = RayContent {
271 content_type: RayHtml::get_type(),
272 origin: RayOrigin::new(),
273 content: message,
274 };
275
276 self.request.payloads.push(content);
277
278 self.send();
279 self
280 }
281
282 pub fn confetti(&mut self) -> &mut Self {
283 let message = RayMessage::Confetti(RayConfetti {
284 label: RayMessageType::Confetti,
285 });
286
287 let content = RayContent {
288 content_type: RayConfetti::get_type(),
289 origin: RayOrigin::new(),
290 content: message,
291 };
292
293 self.request.payloads.push(content);
294
295 self.send();
296 self
297 }
298
299 pub fn charles(&mut self) -> &mut Self {
300 let message = RayMessage::Charles(RayCharles {
301 content: "🎶 🎹 🎷 🕺".to_string(),
302 });
303
304 let content = RayContent {
305 content_type: RayCharles::get_type(),
306 origin: RayOrigin::new(),
307 content: message,
308 };
309
310 self.request.payloads.push(content);
311
312 self.send();
313 self
314 }
315
316 pub fn count(&mut self, _name: &str) -> &mut Self {
317 unimplemented!();
322 }
323
324 pub fn counter_value(&mut self) -> &mut Self {
325 unimplemented!();
326 }
327
328 pub fn clear_counters(&mut self) -> &mut Self {
329 unimplemented!();
330 }
331
332 pub fn disable(&mut self) -> &mut Self {
333 self.is_enabled = false;
334
335 self
336 }
337
338 pub fn disabled(&mut self) -> bool {
339 !self.is_enabled
340 }
341
342 pub fn enable(&mut self) -> &mut Self {
343 self.is_enabled = true;
344
345 self
346 }
347
348 pub fn enabled(&mut self) -> bool {
349 self.is_enabled
350 }
351
352 pub fn file(&mut self) -> &mut Self {
353 unimplemented!();
354 }
355
356 pub fn gray(&mut self) -> &mut Self {
357 unimplemented!();
358 }
359
360 pub fn green(&mut self) -> &mut Self {
361 unimplemented!();
362 }
363
364 pub fn hide(&mut self) -> &mut Self {
365 unimplemented!();
366 }
367
368 pub fn hide_app(&mut self) -> &mut Self {
369 unimplemented!();
370 }
371
372 pub fn image(&mut self) -> &mut Self {
373 unimplemented!();
374 }
375
376 pub fn r#if(&mut self) -> &mut Self {
378 unimplemented!();
379 }
380
381 pub fn json(&mut self) -> &mut Self {
382 unimplemented!();
383 }
384
385 pub fn label(&mut self) -> &mut Self {
386 unimplemented!();
387 }
388
389 pub fn large(&mut self) -> &mut Self {
390 unimplemented!();
391 }
392
393 pub fn limit(&mut self) -> &mut Self {
394 unimplemented!();
395 }
396
397 pub fn link(&mut self) -> &mut Self {
398 unimplemented!();
399 }
400
401 pub fn measure(&mut self) -> &mut Self {
402 unimplemented!();
403 }
404
405 pub fn notify(&mut self) -> &mut Self {
406 unimplemented!();
407 }
408
409 pub fn orange(&mut self) -> &mut Self {
410 unimplemented!();
411 }
412
413 pub fn pass(&mut self) -> &mut Self {
414 unimplemented!();
415 }
416
417 pub fn pause(&mut self) -> &mut Self {
418 unimplemented!();
419 }
420
421 pub fn info(&mut self) -> &mut Self {
422 unimplemented!();
423 }
424
425 pub fn purple(&mut self) -> &mut Self {
426 unimplemented!();
427 }
428
429 pub fn rate_limiter(&mut self) -> &mut Self {
431 unimplemented!();
432 }
433
434 pub fn red(&mut self) -> &mut Self {
435 unimplemented!();
436 }
437
438 pub fn separator(&mut self) -> &mut Self {
439 unimplemented!();
440 }
441
442 pub fn show_app(&mut self) -> &mut Self {
443 unimplemented!();
444 }
445
446 pub fn small(&mut self) -> &mut Self {
447 unimplemented!();
448 }
449
450 pub fn table(&mut self) -> &mut Self {
451 unimplemented!();
452 }
453
454 pub fn to_json(&mut self) -> &mut Self {
455 unimplemented!();
456 }
457
458 pub fn trace(&mut self) -> &mut Self {
459 unimplemented!();
460 }
461
462 pub fn url(&mut self) -> &mut Self {
463 unimplemented!();
464 }
465
466 pub fn xml(&mut self) -> &mut Self {
467 unimplemented!();
468 }
469}