1use serde::Serializer;
2
3#[cfg(doc)]
4use super::Ui;
5
6const JSON_SKIP_MESSAGE: &str = "UI_INTERNAL_SKIP";
7
8pub trait Message {
13 fn text(self) -> String
20 where
21 Self: Sized,
22 {
23 String::new()
24 }
25
26 #[doc(hidden)]
27 fn print_text(self)
28 where
29 Self: Sized,
30 {
31 let text = self.text();
32 if !text.is_empty() {
33 println!("{text}");
34 }
35 }
36
37 fn structured<S: Serializer>(self, ser: S) -> Result<S::Ok, S::Error>
42 where
43 Self: Sized,
44 {
45 Self::skip_structured(ser)
46 }
47
48 #[doc(hidden)]
49 fn skip_structured<S: Serializer>(_ser: S) -> Result<S::Ok, S::Error> {
50 Err(serde::ser::Error::custom(JSON_SKIP_MESSAGE))
51 }
52
53 #[doc(hidden)]
54 fn print_json(self)
55 where
56 Self: Sized,
57 {
58 let mut buf = Vec::with_capacity(128);
59 let mut serializer = serde_json::Serializer::new(&mut buf);
60 match self.structured(&mut serializer) {
61 Ok(_) => {
62 let string = unsafe {
63 String::from_utf8_unchecked(buf)
65 };
66 println!("{string}");
67 }
68 Err(err) => {
69 if err.to_string() != JSON_SKIP_MESSAGE {
70 panic!("JSON serialization of UI message must not fail: {err}")
71 }
72 }
73 }
74 }
75}
76
77impl Message for &str {
78 fn text(self) -> String {
79 self.to_string()
80 }
81}
82
83impl Message for String {
84 fn text(self) -> String {
85 self
86 }
87}