1use crate::{
6 AnyHandle, AsHandleRef, Channel, ChannelMessageStream, ChannelWriter, Error, Handle,
7 HandleBased, HandleInfo, MessageBuf,
8};
9use fidl::epitaph::ChannelEpitaphExt;
10use fidl_fuchsia_fdomain as proto;
11use fuchsia_sync::Mutex;
12use futures::{Stream, StreamExt, TryStream};
13use std::cell::RefCell;
14use std::marker::PhantomData;
15use std::sync::Arc;
16use std::task::Poll;
17
18pub trait FDomainFlexibleIntoResult<T> {
19 fn into_result_fdomain<P: ProtocolMarker>(
20 self,
21 method_name: &'static str,
22 ) -> Result<T, fidl::Error>;
23}
24
25impl<T> FDomainFlexibleIntoResult<T> for fidl::encoding::Flexible<T> {
26 fn into_result_fdomain<P: ProtocolMarker>(
27 self,
28 method_name: &'static str,
29 ) -> Result<T, fidl::Error> {
30 match self {
31 fidl::encoding::Flexible::Ok(ok) => Ok(ok),
32 fidl::encoding::Flexible::FrameworkErr(fidl::encoding::FrameworkErr::UnknownMethod) => {
33 Err(fidl::Error::UnsupportedMethod { method_name, protocol_name: P::DEBUG_NAME })
34 }
35 }
36 }
37}
38
39impl<T, E> FDomainFlexibleIntoResult<Result<T, E>> for fidl::encoding::FlexibleResult<T, E> {
40 fn into_result_fdomain<P: ProtocolMarker>(
41 self,
42 method_name: &'static str,
43 ) -> Result<Result<T, E>, fidl::Error> {
44 match self {
45 fidl::encoding::FlexibleResult::Ok(ok) => Ok(Ok(ok)),
46 fidl::encoding::FlexibleResult::DomainErr(err) => Ok(Err(err)),
47 fidl::encoding::FlexibleResult::FrameworkErr(
48 fidl::encoding::FrameworkErr::UnknownMethod,
49 ) => Err(fidl::Error::UnsupportedMethod { method_name, protocol_name: P::DEBUG_NAME }),
50 }
51 }
52}
53
54#[derive(Debug)]
55pub struct FDomainProxyChannel(Mutex<ChannelMessageStream>, ChannelWriter);
56
57impl FDomainProxyChannel {
58 pub fn on_closed(&self) -> crate::OnFDomainSignals {
59 self.1.as_channel().on_closed()
60 }
61
62 pub fn read_etc(
63 &self,
64 ctx: &mut std::task::Context<'_>,
65 bytes: &mut Vec<u8>,
66 handles: &mut Vec<HandleInfo>,
67 ) -> Poll<Result<(), Option<crate::Error>>> {
68 let Some(got) = std::task::ready!(self.0.lock().poll_next_unpin(ctx)) else {
69 return Poll::Ready(Err(Some(Error::StreamingAborted)));
70 };
71
72 match got {
73 Ok(got) => {
74 *bytes = got.bytes;
75 *handles = got.handles;
76 Poll::Ready(Ok(()))
77 }
78 Err(Error::FDomain(proto::Error::TargetError(i)))
79 if i == fidl::Status::PEER_CLOSED.into_raw() =>
80 {
81 Poll::Ready(Err(None))
82 }
83 Err(e) => Poll::Ready(Err(Some(e))),
84 }
85 }
86}
87
88impl ::fidl::encoding::ProxyChannelBox<FDomainResourceDialect> for FDomainProxyChannel {
89 fn recv_etc_from(
90 &self,
91 ctx: &mut std::task::Context<'_>,
92 buf: &mut MessageBuf,
93 ) -> Poll<Result<(), Option<Error>>> {
94 let Some(got) = std::task::ready!(self.0.lock().poll_next_unpin(ctx)) else {
95 return Poll::Ready(Err(Some(Error::StreamingAborted)));
96 };
97
98 match got {
99 Ok(got) => {
100 *buf = got;
101 Poll::Ready(Ok(()))
102 }
103 Err(Error::FDomain(proto::Error::TargetError(i)))
104 if i == fidl::Status::PEER_CLOSED.into_raw() =>
105 {
106 Poll::Ready(Err(None))
107 }
108 Err(e) => Poll::Ready(Err(Some(e))),
109 }
110 }
111
112 fn write_etc(&self, bytes: &[u8], handles: &mut [HandleInfo]) -> Result<(), Option<Error>> {
113 let mut handle_ops = Vec::new();
114 for handle in handles {
115 handle_ops.push(crate::channel::HandleOp::Move(
116 std::mem::replace(&mut handle.handle, AnyHandle::invalid()).into(),
117 handle.rights,
118 ));
119 }
120 let _ = self.1.fdomain_write_etc(bytes, handle_ops);
121 Ok(())
122 }
123
124 fn is_closed(&self) -> bool {
125 self.0.lock().is_closed()
126 }
127
128 fn unbox(self) -> Channel {
129 self.0.into_inner().rejoin(self.1)
130 }
131
132 fn as_channel(&self) -> &Channel {
133 self.1.as_channel()
134 }
135}
136
137#[derive(Debug, Copy, Clone, Default)]
138pub struct FDomainResourceDialect;
139impl ::fidl::encoding::ResourceDialect for FDomainResourceDialect {
140 type Handle = Handle;
141 type MessageBufEtc = MessageBuf;
142 type ProxyChannel = Channel;
143
144 #[inline]
145 fn with_tls_buf<R>(f: impl FnOnce(&mut ::fidl::encoding::TlsBuf<Self>) -> R) -> R {
146 thread_local!(static TLS_BUF: RefCell<::fidl::encoding::TlsBuf<FDomainResourceDialect>> =
147 RefCell::new(::fidl::encoding::TlsBuf::default()));
148 TLS_BUF.with(|buf| f(&mut buf.borrow_mut()))
149 }
150}
151
152impl ::fidl::encoding::MessageBufFor<FDomainResourceDialect> for MessageBuf {
153 fn new() -> MessageBuf {
154 MessageBuf { bytes: Vec::new(), handles: Vec::new() }
155 }
156
157 fn split_mut(&mut self) -> (&mut Vec<u8>, &mut Vec<HandleInfo>) {
158 (&mut self.bytes, &mut self.handles)
159 }
160}
161
162impl Into<::fidl::TransportError> for Error {
163 fn into(self) -> ::fidl::TransportError {
164 match self {
165 Error::FDomain(proto::Error::TargetError(i)) => {
166 ::fidl::TransportError::Status(fidl::Status::err_from_raw(i))
167 }
168 Error::SocketWrite(proto::WriteSocketError {
169 error: proto::Error::TargetError(i),
170 ..
171 }) => ::fidl::TransportError::Status(fidl::Status::err_from_raw(i)),
172 Error::ChannelWrite(proto::WriteChannelError::Error(proto::Error::TargetError(i))) => {
173 ::fidl::TransportError::Status(fidl::Status::err_from_raw(i))
174 }
175 Error::ChannelWrite(proto::WriteChannelError::OpErrors(ops)) => {
176 let Some(op) = ops.into_iter().find_map(|x| x) else {
177 let err = Box::<dyn std::error::Error + Send + Sync>::from(
178 "Channel write handle operation reported failure with no status!"
179 .to_owned(),
180 );
181 return ::fidl::TransportError::Other(err.into());
182 };
183 let op = *op;
184 Error::FDomain(op).into()
185 }
186 other => ::fidl::TransportError::Other(std::sync::Arc::new(other)),
187 }
188 }
189}
190
191impl ::fidl::encoding::ProxyChannelFor<FDomainResourceDialect> for Channel {
192 type Boxed = FDomainProxyChannel;
193 type Error = Error;
194 type HandleDisposition = HandleInfo;
195
196 fn boxed(self) -> Self::Boxed {
197 let (a, b, _) = self.force_stream();
198 FDomainProxyChannel(Mutex::new(a), b)
199 }
200
201 fn write_etc(&self, bytes: &[u8], handles: &mut [HandleInfo]) -> Result<(), Option<Error>> {
202 let mut handle_ops = Vec::new();
203 for handle in handles {
204 handle_ops.push(crate::channel::HandleOp::Move(
205 std::mem::replace(&mut handle.handle, AnyHandle::invalid()).into(),
206 handle.rights,
207 ));
208 }
209 let _ = self.fdomain_write_etc(bytes, handle_ops);
210 Ok(())
211 }
212}
213
214impl ::fidl::epitaph::ChannelLike for Channel {
215 fn write_epitaph(&self, bytes: &[u8]) -> Result<(), ::fidl::TransportError> {
216 let _ = self.write(bytes, vec![]);
217 Ok(())
218 }
219}
220
221impl ::fidl::encoding::HandleFor<FDomainResourceDialect> for Handle {
222 type HandleInfo = HandleInfo;
225
226 fn invalid() -> Self {
227 Handle::invalid()
228 }
229
230 fn is_invalid(&self) -> bool {
231 self.client.upgrade().is_none()
232 }
233}
234
235impl ::fidl::encoding::HandleDispositionFor<FDomainResourceDialect> for HandleInfo {
236 fn from_handle(handle: Handle, object_type: fidl::ObjectType, rights: fidl::Rights) -> Self {
237 HandleInfo { handle: AnyHandle::from_handle(handle, object_type), rights }
238 }
239}
240
241impl ::fidl::encoding::HandleInfoFor<FDomainResourceDialect> for HandleInfo {
242 fn consume(
243 &mut self,
244 expected_object_type: fidl::ObjectType,
245 expected_rights: fidl::Rights,
246 ) -> Result<Handle, ::fidl::Error> {
247 let handle_info = std::mem::replace(
248 self,
249 HandleInfo {
250 handle: crate::AnyHandle::Unknown(Handle::invalid(), fidl::ObjectType::NONE),
251 rights: fidl::Rights::empty(),
252 },
253 );
254 let received_object_type = handle_info.handle.object_type();
255 if expected_object_type != fidl::ObjectType::NONE
256 && received_object_type != fidl::ObjectType::NONE
257 && expected_object_type != received_object_type
258 {
259 return Err(fidl::Error::IncorrectHandleSubtype {
260 expected: fidl::ObjectType::NONE,
264 received: fidl::ObjectType::NONE,
265 });
266 }
267
268 let received_rights = handle_info.rights;
269 if expected_rights != fidl::Rights::SAME_RIGHTS
270 && received_rights != fidl::Rights::SAME_RIGHTS
271 && expected_rights != received_rights
272 {
273 if !received_rights.contains(expected_rights) {
274 return Err(fidl::Error::MissingExpectedHandleRights {
275 missing_rights: fidl::Rights::empty(),
277 });
278 }
279
280 }
284 Ok(handle_info.handle.into())
285 }
286
287 fn drop_in_place(&mut self) {
288 *self = HandleInfo {
289 handle: crate::AnyHandle::Unknown(Handle::invalid(), fidl::ObjectType::NONE),
290 rights: fidl::Rights::empty(),
291 };
292 }
293}
294
295impl ::fidl::encoding::EncodableAsHandle for crate::Event {
296 type Dialect = FDomainResourceDialect;
297}
298
299impl ::fidl::encoding::EncodableAsHandle for crate::EventPair {
300 type Dialect = FDomainResourceDialect;
301}
302
303impl ::fidl::encoding::EncodableAsHandle for crate::Socket {
304 type Dialect = FDomainResourceDialect;
305}
306
307impl ::fidl::encoding::EncodableAsHandle for crate::Channel {
308 type Dialect = FDomainResourceDialect;
309}
310
311impl ::fidl::encoding::EncodableAsHandle for crate::Vmo {
312 type Dialect = FDomainResourceDialect;
313}
314
315impl ::fidl::encoding::EncodableAsHandle for crate::Handle {
316 type Dialect = FDomainResourceDialect;
317}
318
319impl<T: ProtocolMarker> ::fidl::encoding::EncodableAsHandle for ClientEnd<T> {
320 type Dialect = FDomainResourceDialect;
321}
322
323impl<T: ProtocolMarker> ::fidl::encoding::EncodableAsHandle for ServerEnd<T> {
324 type Dialect = FDomainResourceDialect;
325}
326
327pub trait ProtocolMarker: Sized + Send + Sync + 'static {
330 type Proxy: Proxy<Protocol = Self>;
333
334 type RequestStream: RequestStream<Protocol = Self>;
336
337 const DEBUG_NAME: &'static str;
342}
343
344pub trait DiscoverableProtocolMarker: ProtocolMarker {
357 const PROTOCOL_NAME: &'static str = <Self as ProtocolMarker>::DEBUG_NAME;
359}
360
361pub trait Proxy: Sized + Send + Sync {
363 type Protocol: ProtocolMarker<Proxy = Self>;
365
366 fn from_channel(inner: Channel) -> Self;
368
369 fn into_channel(self) -> Result<Channel, Self>;
375
376 fn into_client_end(self) -> Result<ClientEnd<Self::Protocol>, Self> {
382 match self.into_channel() {
383 Ok(channel) => Ok(ClientEnd::new(channel)),
384 Err(proxy) => Err(proxy),
385 }
386 }
387
388 fn as_channel(&self) -> &Channel;
394
395 fn domain(&self) -> Arc<crate::Client> {
400 self.as_channel().domain()
401 }
402
403 fn on_closed(&self) -> crate::OnFDomainSignals {
406 self.as_channel().on_closed()
407 }
408}
409
410pub trait RequestStream: Sized + Send + Stream + TryStream<Error = fidl::Error> + Unpin {
412 type Protocol: ProtocolMarker<RequestStream = Self>;
414
415 type ControlHandle: ControlHandle;
417
418 fn control_handle(&self) -> Self::ControlHandle;
421
422 fn from_channel(inner: Channel) -> Self;
424
425 fn into_inner(self) -> (std::sync::Arc<fidl::ServeInner<FDomainResourceDialect>>, bool);
427
428 fn from_inner(
430 inner: std::sync::Arc<fidl::ServeInner<FDomainResourceDialect>>,
431 is_terminated: bool,
432 ) -> Self;
433}
434
435pub trait ControlHandle {
438 fn shutdown(&self);
441
442 fn shutdown_with_epitaph(&self, status: fidl::Epitaph);
445
446 fn is_closed(&self) -> bool;
448
449 fn on_closed(&self) -> crate::OnFDomainSignals;
452}
453
454pub trait Responder {
457 type ControlHandle: ControlHandle;
459
460 fn control_handle(&self) -> &Self::ControlHandle;
462
463 fn drop_without_shutdown(self);
468}
469
470pub type Request<Marker> = <<Marker as ProtocolMarker>::RequestStream as futures::TryStream>::Ok;
472
473#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
475pub struct ClientEnd<T: ProtocolMarker> {
476 inner: Channel,
477 phantom: PhantomData<T>,
478}
479
480impl<T: ProtocolMarker> ClientEnd<T> {
481 pub fn new(inner: Channel) -> Self {
483 ClientEnd { inner, phantom: PhantomData }
484 }
485
486 pub fn channel(&self) -> &Channel {
488 &self.inner
489 }
490
491 pub fn into_channel(self) -> Channel {
493 self.inner
494 }
495
496 pub fn invalid() -> Self {
498 ClientEnd { inner: Channel::invalid(), phantom: PhantomData }
499 }
500
501 pub fn is_invalid(&self) -> bool {
503 self.inner.is_invalid()
504 }
505}
506
507impl<'c, T: ProtocolMarker> ClientEnd<T> {
508 pub fn into_proxy(self) -> T::Proxy {
510 T::Proxy::from_channel(self.inner)
511 }
512}
513
514impl<T: ProtocolMarker> From<ClientEnd<T>> for Handle {
515 fn from(client: ClientEnd<T>) -> Handle {
516 client.into_channel().into()
517 }
518}
519
520impl<T: ProtocolMarker> From<Handle> for ClientEnd<T> {
521 fn from(handle: Handle) -> Self {
522 ClientEnd { inner: handle.into(), phantom: PhantomData }
523 }
524}
525
526impl<T: ProtocolMarker> From<Channel> for ClientEnd<T> {
527 fn from(chan: Channel) -> Self {
528 ClientEnd { inner: chan, phantom: PhantomData }
529 }
530}
531
532impl<T: ProtocolMarker> AsHandleRef for ClientEnd<T> {
533 fn as_handle_ref(&self) -> crate::HandleRef<'_> {
534 AsHandleRef::as_handle_ref(&self.inner)
535 }
536
537 fn object_type() -> fidl::ObjectType {
538 <Channel as AsHandleRef>::object_type()
539 }
540}
541
542impl<T: ProtocolMarker> HandleBased for ClientEnd<T> {
543 fn close(self) -> impl Future<Output = Result<(), Error>> {
544 let h = <Self as Into<Handle>>::into(self);
545 Handle::close(h)
546 }
547
548 fn duplicate_handle(&self, rights: fidl::Rights) -> impl Future<Output = Result<Self, Error>> {
549 let fut = self.as_handle_ref().duplicate(rights);
550 async move { fut.await.map(|handle| Self::from(handle)) }
551 }
552
553 fn replace_handle(self, rights: fidl::Rights) -> impl Future<Output = Result<Self, Error>> {
554 let h = <Self as Into<Handle>>::into(self);
555 async move { h.replace(rights).await.map(|handle| Self::from(handle)) }
556 }
557
558 fn into_handle(self) -> Handle {
559 self.into()
560 }
561
562 fn from_handle(handle: Handle) -> Self {
563 Self::from(handle)
564 }
565
566 fn into_handle_based<H: HandleBased>(self) -> H {
567 H::from_handle(self.into_handle())
568 }
569
570 fn from_handle_based<H: HandleBased>(h: H) -> Self {
571 Self::from_handle(h.into_handle())
572 }
573
574 fn invalidate(&mut self) {
575 self.inner.invalidate();
576 }
577}
578
579#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
581pub struct ServerEnd<T: ProtocolMarker> {
582 inner: Channel,
583 phantom: PhantomData<T>,
584}
585
586impl<T: ProtocolMarker> ServerEnd<T> {
587 pub fn new(inner: Channel) -> ServerEnd<T> {
589 ServerEnd { inner, phantom: PhantomData }
590 }
591
592 pub fn channel(&self) -> &Channel {
594 &self.inner
595 }
596
597 pub fn into_channel(self) -> Channel {
599 self.inner
600 }
601
602 pub fn into_stream(self) -> T::RequestStream
604 where
605 T: ProtocolMarker,
606 {
607 T::RequestStream::from_channel(self.inner)
608 }
609
610 pub fn into_stream_and_control_handle(
613 self,
614 ) -> (T::RequestStream, <T::RequestStream as RequestStream>::ControlHandle)
615 where
616 T: ProtocolMarker,
617 {
618 let stream = self.into_stream();
619 let control_handle = stream.control_handle();
620 (stream, control_handle)
621 }
622
623 pub fn close_with_epitaph(
625 self,
626 status: impl Into<Result<(), fidl::Status>>,
627 ) -> Result<(), fidl::Error> {
628 self.inner.close_with_epitaph(status)
629 }
630
631 pub fn invalid() -> Self {
633 ServerEnd { inner: Channel::invalid(), phantom: PhantomData }
634 }
635
636 pub fn is_invalid(&self) -> bool {
638 self.inner.is_invalid()
639 }
640}
641
642impl<T: ProtocolMarker> From<ServerEnd<T>> for Handle {
643 fn from(server: ServerEnd<T>) -> Handle {
644 server.into_channel().into()
645 }
646}
647
648impl<T: ProtocolMarker> From<Handle> for ServerEnd<T> {
649 fn from(handle: Handle) -> Self {
650 ServerEnd { inner: handle.into(), phantom: PhantomData }
651 }
652}
653
654impl<T: ProtocolMarker> From<Channel> for ServerEnd<T> {
655 fn from(chan: Channel) -> Self {
656 ServerEnd { inner: chan, phantom: PhantomData }
657 }
658}
659
660impl<T: ProtocolMarker> AsHandleRef for ServerEnd<T> {
661 fn as_handle_ref(&self) -> crate::HandleRef<'_> {
662 AsHandleRef::as_handle_ref(&self.inner)
663 }
664
665 fn object_type() -> fidl::ObjectType {
666 <Channel as AsHandleRef>::object_type()
667 }
668}
669
670impl<T: ProtocolMarker> HandleBased for ServerEnd<T> {
671 fn close(self) -> impl Future<Output = Result<(), Error>> {
672 let h = <Self as Into<Handle>>::into(self);
673 Handle::close(h)
674 }
675
676 fn duplicate_handle(&self, rights: fidl::Rights) -> impl Future<Output = Result<Self, Error>> {
677 let fut = self.as_handle_ref().duplicate(rights);
678 async move { fut.await.map(|handle| Self::from(handle)) }
679 }
680
681 fn replace_handle(self, rights: fidl::Rights) -> impl Future<Output = Result<Self, Error>> {
682 let h = <Self as Into<Handle>>::into(self);
683 async move { h.replace(rights).await.map(|handle| Self::from(handle)) }
684 }
685
686 fn into_handle(self) -> Handle {
687 self.into()
688 }
689
690 fn from_handle(handle: Handle) -> Self {
691 Self::from(handle)
692 }
693
694 fn into_handle_based<H: HandleBased>(self) -> H {
695 H::from_handle(self.into_handle())
696 }
697
698 fn from_handle_based<H: HandleBased>(h: H) -> Self {
699 Self::from_handle(h.into_handle())
700 }
701
702 fn invalidate(&mut self) {
703 self.inner.invalidate();
704 }
705}