1use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::{concat, stringify};
8
9use fidl_next_codec::{
10 munge, Decode, DecodeError, Encodable, EncodableOption, Encode, EncodeError, EncodeOption,
11 EncodeOptionRef, EncodeRef, FromWire, FromWireOption, FromWireOptionRef, FromWireRef, Slot,
12 Wire,
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: 'static, T: Wire> Wire for $name<P, T> {
43 type Decoded<'de> = $name<P, T::Decoded<'de>>;
44
45 #[inline]
46 fn zero_padding(out: &mut MaybeUninit<Self>) {
47 munge!(let Self { transport, _protocol: _ } = out);
48 T::zero_padding(transport);
49 }
50 }
51
52 impl<P, T> $name<P, T> {
53 #[doc = concat!(
54 "Converts from `&",
55 stringify!($name),
56 "<P, T>` to `",
57 stringify!($name),
58 "<P, &T>`.",
59 )]
60 pub fn as_ref(&self) -> $name<P, &T> {
61 $name { transport: &self.transport, _protocol: PhantomData }
62 }
63
64 pub fn from_untyped(transport: T) -> Self {
66 Self { transport, _protocol: PhantomData }
67 }
68
69 pub fn into_untyped(self) -> T {
71 self.transport
72 }
73 }
74
75 unsafe impl<D, P, T> Decode<D> for $name<P, T>
78 where
79 D: ?Sized,
80 P: 'static,
81 T: Decode<D>,
82 {
83 fn decode(slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
84 munge!(let Self { transport, _protocol: _ } = slot);
85 T::decode(transport, decoder)
86 }
87 }
88
89 impl<P, T> Encodable for $name<P, T>
90 where
91 T: Encodable,
92 P: 'static,
93 {
94 type Encoded = $name<P, T::Encoded>;
95 }
96
97 impl<P, T> EncodableOption for $name<P, T>
98 where
99 T: EncodableOption,
100 P: 'static,
101 {
102 type EncodedOption = $name<P, T::EncodedOption>;
103 }
104
105 unsafe impl<E, P, T> Encode<E> for $name<P, T>
108 where
109 E: ?Sized,
110 P: 'static,
111 T: Encode<E>,
112 {
113 fn encode(
114 self,
115 encoder: &mut E,
116 out: &mut MaybeUninit<Self::Encoded>,
117 ) -> Result<(), EncodeError> {
118 munge!(let Self::Encoded { transport, _protocol: _ } = out);
119 self.transport.encode(encoder, transport)
120 }
121 }
122
123 unsafe impl<E, P, T> EncodeRef<E> for $name<P, T>
127 where
128 E: ?Sized,
129 P: 'static,
130 T: EncodeRef<E>,
131 {
132 fn encode_ref(
133 &self,
134 encoder: &mut E,
135 out: &mut MaybeUninit<Self::Encoded>,
136 ) -> Result<(), EncodeError> {
137 self.as_ref().encode(encoder, out)
138 }
139 }
140
141 unsafe impl<E, P, T> EncodeOption<E> for $name<P, T>
145 where
146 E: ?Sized,
147 P: 'static,
148 T: EncodeOption<E>,
149 {
150 fn encode_option(
151 this: Option<Self>,
152 encoder: &mut E,
153 out: &mut MaybeUninit<Self::EncodedOption>,
154 ) -> Result<(), EncodeError> {
155 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
156 T::encode_option(this.map(|this| this.transport), encoder, transport)
157 }
158 }
159
160 unsafe impl<E, P, T> EncodeOptionRef<E> for $name<P, T>
164 where
165 E: ?Sized,
166 P: 'static,
167 T: EncodeOptionRef<E>,
168 {
169 fn encode_option_ref(
170 this: Option<&Self>,
171 encoder: &mut E,
172 out: &mut MaybeUninit<Self::EncodedOption>,
173 ) -> Result<(), EncodeError> {
174 munge!(let Self::EncodedOption { transport, _protocol: _ } = out);
175 T::encode_option_ref(this.map(|this| &this.transport), encoder, transport)
176 }
177 }
178
179 impl<P, T, U> FromWire<$name<P, U>> for $name<P, T>
180 where
181 T: FromWire<U>,
182 {
183 #[inline]
184 fn from_wire(wire: $name<P, U>) -> Self {
185 $name {
186 transport: T::from_wire(wire.transport),
187 _protocol: PhantomData,
188 }
189 }
190 }
191
192 impl<P, T, U> FromWireRef<$name<P, U>> for $name<P, T>
193 where
194 T: FromWireRef<U>,
195 {
196 #[inline]
197 fn from_wire_ref(wire: &$name<P, U>) -> Self {
198 $name {
199 transport: T::from_wire_ref(&wire.transport),
200 _protocol: PhantomData,
201 }
202 }
203 }
204
205 impl<P, T, U> FromWireOption<$name<P, U>> for $name<P, T>
206 where
207 P: 'static,
208 T: FromWireOption<U>,
209 U: Wire,
210 {
211 #[inline]
212 fn from_wire_option(wire: $name<P, U>) -> Option<Self> {
213 T::from_wire_option(wire.transport).map(|transport| $name {
214 transport,
215 _protocol: PhantomData,
216 })
217 }
218 }
219
220 impl<P, T, U> FromWireOptionRef<$name<P, U>> for $name<P, T>
221 where
222 P: 'static,
223 T: FromWireOptionRef<U>,
224 U: Wire,
225 {
226 #[inline]
227 fn from_wire_option_ref(wire: &$name<P, U>) -> Option<Self> {
228 T::from_wire_option_ref(&wire.transport).map(|transport| $name {
229 transport,
230 _protocol: PhantomData,
231 })
232 }
233 }
234
235 #[cfg(feature = "compat")]
236 impl<P1, P2, T> From<$name<P1, T>> for ::fidl::endpoints::$name<P2>
237 where
238 ::fidl::Channel: From<T>,
239 P2: From<P1>,
240 {
241 fn from(from: $name<P1, T>) -> Self {
242 Self::new(from.transport.into())
243 }
244 }
245 };
246}
247
248endpoint! {
249 ClientEnd
251}
252
253endpoint! {
254 ServerEnd
256}