oxygengine_editor_tools/
simp.rs

1//! Standarized Interprocess Messaging Protocol.
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct SimpMessageId {
5    pub id: String,
6    pub version: u32,
7}
8
9impl SimpMessageId {
10    pub fn new(id: impl ToString, version: u32) -> Self {
11        Self {
12            id: id.to_string(),
13            version,
14        }
15    }
16}
17
18impl std::fmt::Display for SimpMessageId {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        write!(f, "{} v{}", self.id, self.version)
21    }
22}
23
24#[derive(Debug, Clone)]
25pub struct SimpMessage {
26    pub id: SimpMessageId,
27    pub text_data: Option<String>,
28    pub binary_data: Option<Vec<u8>>,
29}
30
31impl SimpMessage {
32    pub fn new(id: SimpMessageId, text_data: String, binary_data: Vec<u8>) -> Self {
33        Self {
34            id,
35            text_data: Some(text_data),
36            binary_data: Some(binary_data),
37        }
38    }
39
40    pub fn text(id: SimpMessageId, text_data: String) -> Self {
41        Self {
42            id,
43            text_data: Some(text_data),
44            binary_data: None,
45        }
46    }
47
48    pub fn binary(id: SimpMessageId, binary_data: Vec<u8>) -> Self {
49        Self {
50            id,
51            text_data: None,
52            binary_data: Some(binary_data),
53        }
54    }
55
56    pub fn empty(id: SimpMessageId) -> Self {
57        Self {
58            id,
59            text_data: None,
60            binary_data: None,
61        }
62    }
63}
64
65impl std::fmt::Display for SimpMessage {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "* Message: {}", self.id)?;
68        if let Some(text) = &self.text_data {
69            write!(f, "- Text data:\n{}", text)?;
70        }
71        if let Some(binary) = &self.binary_data {
72            write!(f, "- Binary data: {} bytes", binary.len())?;
73        }
74        Ok(())
75    }
76}
77
78pub trait SimpSender
79where
80    Self: Sized,
81{
82    type Error;
83
84    fn write(&mut self, message: SimpMessage) -> Result<(), Self::Error>;
85
86    fn write_iter<I>(&mut self, iter: I) -> Result<(), Self::Error>
87    where
88        I: Iterator<Item = SimpMessage>,
89    {
90        for message in iter {
91            self.write(message)?;
92        }
93        Ok(())
94    }
95}
96
97impl SimpSender for () {
98    type Error = ();
99
100    fn write(&mut self, _: SimpMessage) -> Result<(), Self::Error> {
101        Ok(())
102    }
103}
104
105pub trait SimpReceiver
106where
107    Self: Sized,
108{
109    type Error;
110
111    fn read(&mut self) -> Option<Result<SimpMessage, Self::Error>>;
112
113    fn read_iter(&mut self) -> SimpReadIter<Self> {
114        SimpReadIter(self)
115    }
116}
117
118impl SimpReceiver for () {
119    type Error = ();
120
121    fn read(&mut self) -> Option<Result<SimpMessage, Self::Error>> {
122        None
123    }
124}
125
126pub struct SimpReadIter<'a, R>(&'a mut R)
127where
128    R: SimpReceiver;
129
130impl<'a, R> Iterator for SimpReadIter<'a, R>
131where
132    R: SimpReceiver,
133{
134    type Item = Result<SimpMessage, R::Error>;
135
136    fn next(&mut self) -> Option<Self::Item> {
137        self.0.read()
138    }
139}
140
141pub trait SimpChannel: SimpSender + SimpReceiver {}