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
38const START: u16 = i16::MAX as u16;
40
41impl MessageId {
42 pub const ERROR_MESSAGE: Self = unsafe { Self::new_unchecked(START) };
44
45 #[doc(hidden)]
47 #[inline]
48 pub const fn new(id: u16) -> Option<Self> {
49 let Some(value) = NonZeroU16::new(id) else {
50 return None;
51 };
52
53 Some(Self(value))
54 }
55
56 #[doc(hidden)]
58 #[inline]
59 pub const fn get(&self) -> u16 {
60 self.0.get()
61 }
62
63 #[doc(hidden)]
69 #[inline]
70 pub const unsafe fn new_unchecked(id: u16) -> Self {
71 Self(unsafe { NonZeroU16::new_unchecked(id) })
72 }
73}
74
75pub trait Endpoint
76where
77 Self: 'static,
78{
79 const ID: MessageId;
81
82 type Response<'de>: Decode<'de, Binary, Global>;
84
85 #[doc(hidden)]
86 fn __do_not_implement_endpoint();
87}
88
89pub trait Broadcast
93where
94 Self: 'static,
95{
96 const ID: MessageId;
98
99 type Event<'de>: Event<Broadcast = Self> + Decode<'de, Binary, Global>;
101
102 #[doc(hidden)]
103 fn __do_not_implement_broadcast();
104}
105
106pub trait Request
110where
111 Self: Encode<Binary>,
112{
113 type Endpoint: Endpoint;
115
116 #[doc(hidden)]
117 fn __do_not_implement_request();
118}
119
120pub trait Event
124where
125 Self: Encode<Binary>,
126{
127 type Broadcast: Broadcast;
129
130 #[doc(hidden)]
131 fn __do_not_implement_event();
132}
133
134#[derive(Debug, Clone, Copy, Encode, Decode)]
136#[doc(hidden)]
137#[musli(packed)]
138pub struct RequestHeader {
139 pub serial: u32,
141 pub id: u16,
143}
144
145#[derive(Debug, Clone, Encode, Decode)]
147#[doc(hidden)]
148#[musli(packed)]
149pub struct ResponseHeader {
150 pub serial: u32,
152 pub broadcast: u16,
155 pub error: u16,
157}
158
159#[derive(Debug, Clone, Encode, Decode)]
161#[doc(hidden)]
162#[musli(packed)]
163pub struct ErrorMessage<'de> {
164 pub message: &'de str,
166}