1use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::{concat, stringify};
8
9use fidl_next_codec::{
10 Decode, DecodeError, Encodable, EncodableOption, Encode, EncodeError, EncodeOption,
11 EncodeOptionRef, EncodeRef, FromWire, FromWireOption, FromWireOptionRef, FromWireRef, Slot,
12 Wire, munge,
13};
14
15macro_rules! endpoint {
16 (
17 #[doc = $doc:literal]
18 $name:ident
19 ) => {
20 #[doc = $doc]
21 #[derive(Debug)]
22 #[repr(transparent)]
23 pub struct $name<
24 P,
25 #[cfg(feature = "fuchsia")]
26 T = zx::Channel,
27 #[cfg(not(feature = "fuchsia"))]
28 T,
29 > {
30 transport: T,
31 _protocol: PhantomData<P>,
32 }
33
34 unsafe impl<P, T: Send> Send for $name<P, T> {}
35
36 unsafe impl<P, T: Sync> Sync for $name<P, T> {}
37
38 unsafe impl<P: 'static, T: Wire> Wire for $name<P, T> {
47 type Decoded<'de> = $name<P, T::Decoded<'de>>;
48
49 #[inline]
50 fn zero_padding(out: &mut MaybeUninit<Self>) {
51 munge!(let Self { transport, _protocol: _ } = out);
52 T::zero_padding(transport);
53 }
54 }
55
56 impl<P, T> $name<P, T> {
57 #[doc = concat!(
58 "Converts from `&",
59 stringify!($name),
60 "<P, T>` to `",
61 stringify!($name),
62 "<P, &T>`.",
63 )]
64 pub fn as_ref(&self) -> $name<P, &T> {
65 $name { transport: &self.transport, _protocol: PhantomData }
66 }
67
68 pub fn from_untyped(transport: T) -> Self {
70 Self { transport, _protocol: PhantomData }
71 }
72
73 pub fn into_untyped(self) -> T {
75 self.transport
76 }
77 }
78
79 unsafe impl<D, P, T> Decode<D> for $name<P, T>
82 where
83 D: ?Sized,
84 P: 'static,
85 T: Decode<D>,
86 {
87 fn decode(slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
88 munge!(let Self { transport, _protocol: _ } = slot);
89 T::decode(transport, decoder)
90 }
91 }
92
93 impl<P, T> Encodable for $name<P, T>
94 where
95 T: Encodable,
96 P: 'static,
97 {
98 type Encoded = $name<P, T::Encoded>;
99 }
100
101 impl<P, T> EncodableOption for $name<P, T>
102 where
103 T: EncodableOption,
104 P: 'static,
105 {
106 type EncodedOption = $name<P, T::EncodedOption>;
107 }
108
109 unsafe impl<E, P, T> Encode<E> for $name<P, T>
112 where
113 E: ?Sized,
114 P: 'static,
115 T: Encode<E>,
116 {
117 fn encode(
118 self,
119 encoder: &mut E,
120 out: &mut MaybeUninit<Self::Encoded>,
121 ) -> Result<(), EncodeError> {
122 munge!(let Self::Encoded { transport, _protocol: _ } = out);
123 self.transport.encode(encoder, transport)
124 }
125 }
126
127 unsafe impl<E, P, T> EncodeRef<E> for $name<P, T>
131 where
132 E: ?Sized,
133 P: 'static,
134 T: EncodeRef<E>,
135 {
136 fn encode_ref(
137 &self,
138 encoder: &mut E,
139 out: &mut MaybeUninit<Self::Encoded>,
140 ) -> Result<(), EncodeError> {
141 self.as_ref().encode(encoder, out)
142 }
143 }
144
145 unsafe impl<E, P, T> EncodeOption<E> for $name<P, T>
149 where
150 E: ?Sized,
151 P: 'static,
152 T: EncodeOption<E>,
153 {
154 fn encode_option(
155 this: Option<Self>,
156 encoder: &mut E,
157 out: &mut MaybeUninit<Self::EncodedOption>,
158 ) -> Result<(), EncodeError> {
159 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
160 T::encode_option(this.map(|this| this.transport), encoder, transport)
161 }
162 }
163
164 unsafe impl<E, P, T> EncodeOptionRef<E> for $name<P, T>
168 where
169 E: ?Sized,
170 P: 'static,
171 T: EncodeOptionRef<E>,
172 {
173 fn encode_option_ref(
174 this: Option<&Self>,
175 encoder: &mut E,
176 out: &mut MaybeUninit<Self::EncodedOption>,
177 ) -> Result<(), EncodeError> {
178 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
179 T::encode_option_ref(this.map(|this| &this.transport), encoder, transport)
180 }
181 }
182
183 impl<P, T, U> FromWire<$name<P, U>> for $name<P, T>
184 where
185 T: FromWire<U>,
186 {
187 #[inline]
188 fn from_wire(wire: $name<P, U>) -> Self {
189 $name {
190 transport: T::from_wire(wire.transport),
191 _protocol: PhantomData,
192 }
193 }
194 }
195
196 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
197 where
198 T: FromWireRef<U>,
199 {
200 #[inline]
201 fn from_wire_ref(wire: &$name<P, U>) -> Self {
202 $name {
203 transport: T::from_wire_ref(&wire.transport),
204 _protocol: PhantomData,
205 }
206 }
207 }
208
209 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
210 where
211 P: 'static,
212 T: FromWireOption<U>,
213 U: Wire,
214 {
215 #[inline]
216 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
217 T::from_wire_option(wire.transport).map(|transport| $name {
218 transport,
219 _protocol: PhantomData,
220 })
221 }
222 }
223
224 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
225 where
226 P: 'static,
227 T: FromWireOptionRef<U>,
228 U: Wire,
229 {
230 #[inline]
231 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
232 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
233 transport,
234 _protocol: PhantomData,
235 })
236 }
237 }
238 };
239}
240
241endpoint! {
242 ClientEnd
244}
245
246endpoint! {
247 ServerEnd
249}