1use core::fmt;
4use core::num::NonZeroU16;
5
6use musli::alloc::Global;
7use musli::mode::Binary;
8use musli::{Decode, Encode};
9
10#[doc(inline)]
11pub use musli_web_macros::define;
12
13pub trait Id
15where
16 Self: 'static + Sized + fmt::Debug,
17{
18 fn id(&self) -> MessageId;
20
21 fn from_id(id: MessageId) -> Self;
23
24 #[doc(hidden)]
25 fn __do_not_implement_id();
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)]
30#[repr(transparent)]
31#[musli(transparent)]
32pub struct MessageId(NonZeroU16);
33
34impl fmt::Display for MessageId {
35 #[inline]
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 self.0.fmt(f)
38 }
39}
40
41impl MessageId {
42 pub const ERROR_MESSAGE: Self = unsafe { Self::new_unchecked((i16::MAX as u16) + 1) };
44
45 pub const EMPTY: Self = unsafe { Self::new_unchecked(u16::MAX) };
64
65 #[inline]
67 pub const fn new(id: u16) -> Option<Self> {
68 let Some(value) = NonZeroU16::new(id) else {
69 return None;
70 };
71
72 Some(Self(value))
73 }
74
75 #[inline]
77 pub const fn get(&self) -> u16 {
78 self.0.get()
79 }
80
81 #[inline]
87 pub const unsafe fn new_unchecked(id: u16) -> Self {
88 Self(unsafe { NonZeroU16::new_unchecked(id) })
89 }
90}
91
92pub trait Decodable {
96 type Type<'de>: Decode<'de, Binary, Global>;
98
99 #[doc(hidden)]
100 fn __do_not_implement_decodable();
101}
102
103pub trait Endpoint
107where
108 Self: 'static,
109 for<'de> Self: Decodable<Type<'de> = Self::Response<'de>>,
110{
111 const ID: MessageId;
113
114 type Response<'de>: Decode<'de, Binary, Global>;
116
117 #[doc(hidden)]
118 fn __do_not_implement_endpoint();
119}
120
121pub trait Broadcast
125where
126 Self: 'static,
127{
128 const ID: MessageId;
130
131 #[doc(hidden)]
132 fn __do_not_implement_broadcast();
133}
134
135pub trait BroadcastWithEvent
137where
138 Self: Broadcast,
139 for<'de> Self: Decodable<Type<'de> = Self::Event<'de>>,
140{
141 type Event<'de>: Event<Broadcast = Self> + Decode<'de, Binary, Global>
143 where
144 Self: 'de;
145
146 #[doc(hidden)]
147 fn __do_not_implement_broadcast_with_event();
148}
149
150pub trait Request
154where
155 Self: Encode<Binary>,
156{
157 type Endpoint: Endpoint;
159
160 #[doc(hidden)]
161 fn __do_not_implement_request();
162}
163
164pub trait Event
168where
169 Self: Encode<Binary>,
170{
171 type Broadcast: Broadcast;
173
174 #[doc(hidden)]
175 fn __do_not_implement_event();
176}
177
178#[derive(Debug, Clone, Copy, Encode, Decode)]
180#[doc(hidden)]
181#[musli(packed)]
182pub struct RequestHeader {
183 pub serial: u32,
185 pub id: u16,
187}
188
189#[derive(Debug, Clone, Encode, Decode)]
191#[doc(hidden)]
192#[musli(packed)]
193pub struct ResponseHeader {
194 pub serial: u32,
196 pub broadcast: u16,
199 pub error: u16,
201}
202
203#[derive(Debug, Clone, Encode, Decode)]
205#[doc(hidden)]
206#[musli(packed)]
207pub struct ErrorMessage<'de> {
208 pub message: &'de str,
210}