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 + fmt::Debug,
17{
18 #[doc(hidden)]
20 fn from_raw(id: u16) -> Option<Self>
21 where
22 Self: Sized;
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)]
27#[repr(transparent)]
28#[musli(transparent)]
29pub struct MessageId(NonZeroU16);
30
31impl fmt::Display for MessageId {
32 #[inline]
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 self.0.fmt(f)
35 }
36}
37
38impl MessageId {
39 pub const ERROR_MESSAGE: Self = unsafe { Self::new_unchecked((i16::MAX as u16) + 1) };
41
42 pub const EMPTY: Self = unsafe { Self::new_unchecked(u16::MAX) };
61
62 #[doc(hidden)]
64 #[inline]
65 pub const fn new(id: u16) -> Option<Self> {
66 if id > i16::MAX as u16 {
67 return None;
68 }
69
70 let Some(value) = NonZeroU16::new(id) else {
71 return None;
72 };
73
74 Some(Self(value))
75 }
76
77 #[doc(hidden)]
79 #[inline]
80 pub const fn get(&self) -> u16 {
81 self.0.get()
82 }
83
84 #[doc(hidden)]
90 #[inline]
91 pub const unsafe fn new_unchecked(id: u16) -> Self {
92 Self(unsafe { NonZeroU16::new_unchecked(id) })
93 }
94}
95
96pub trait Decodable {
100 type Type<'de>: Decode<'de, Binary, Global>;
102
103 #[doc(hidden)]
104 fn __do_not_implement_decodable();
105}
106
107pub trait Endpoint
111where
112 Self: 'static,
113 for<'de> Self: Decodable<Type<'de> = Self::Response<'de>>,
114{
115 const ID: MessageId;
117
118 type Response<'de>: Decode<'de, Binary, Global>;
120
121 #[doc(hidden)]
122 fn __do_not_implement_endpoint();
123}
124
125pub trait Broadcast
129where
130 Self: 'static,
131{
132 const ID: MessageId;
134
135 #[doc(hidden)]
136 fn __do_not_implement_broadcast();
137}
138
139pub trait BroadcastWithEvent
141where
142 Self: Broadcast,
143 for<'de> Self: Decodable<Type<'de> = Self::Event<'de>>,
144{
145 type Event<'de>: Event<Broadcast = Self> + Decode<'de, Binary, Global>
147 where
148 Self: 'de;
149
150 #[doc(hidden)]
151 fn __do_not_implement_broadcast_with_event();
152}
153
154pub trait Request
158where
159 Self: Encode<Binary>,
160{
161 type Endpoint: Endpoint;
163
164 #[doc(hidden)]
165 fn __do_not_implement_request();
166}
167
168pub trait Event
172where
173 Self: Encode<Binary>,
174{
175 type Broadcast: Broadcast;
177
178 #[doc(hidden)]
179 fn __do_not_implement_event();
180}
181
182#[derive(Debug, Clone, Copy, Encode, Decode)]
184#[doc(hidden)]
185#[musli(packed)]
186pub struct RequestHeader {
187 pub serial: u32,
189 pub id: u16,
191}
192
193#[derive(Debug, Clone, Encode, Decode)]
195#[doc(hidden)]
196#[musli(packed)]
197pub struct ResponseHeader {
198 pub serial: u32,
200 pub broadcast: u16,
203 pub error: u16,
205}
206
207#[derive(Debug, Clone, Encode, Decode)]
209#[doc(hidden)]
210#[musli(packed)]
211pub struct ErrorMessage<'de> {
212 pub message: &'de str,
214}