fidl_next_bind/
service.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::marker::PhantomData;
6use core::ops::Deref;
7
8use fidl_next_protocol::ServiceHandler;
9
10/// A discoverable service.
11pub trait DiscoverableService {
12    /// The name of this service.
13    const SERVICE_NAME: &'static str;
14    /// The members of this service.
15    const MEMBER_NAMES: &'static [&'static str];
16}
17
18/// A FIDL service.
19///
20/// # Safety
21///
22/// The associated `Connector` type must be a `#[repr(transparent)]` wrapper around `C`.
23pub trait Service<C>: DiscoverableService {
24    /// The connector for the service. It must be a `#[repr(transparent)]` wrapper around `C`.
25    type Connector;
26}
27
28/// A strongly-typed member connector for a FIDL service.
29#[repr(transparent)]
30pub struct ServiceConnector<S, C> {
31    connector: C,
32    service: PhantomData<S>,
33}
34
35unsafe impl<S, C: Send> Send for ServiceConnector<S, C> {}
36unsafe impl<S, C: Sync> Sync for ServiceConnector<S, C> {}
37
38impl<S, C> ServiceConnector<S, C> {
39    /// Returns a new `ServiceConnector`from an untyped service connector.
40    pub fn from_untyped(connector: C) -> Self {
41        Self { connector, service: PhantomData }
42    }
43}
44
45impl<S: Service<C>, C> Deref for ServiceConnector<S, C> {
46    type Target = S::Connector;
47
48    fn deref(&self) -> &Self::Target {
49        // SAFETY: `S::Connector` is a `#[repr(transparent)]` wrapper around `C`.
50        unsafe { &*(self as *const Self).cast::<S::Connector>() }
51    }
52}
53
54/// A service which dispatches incoming connections to a handler.
55pub trait DispatchServiceHandler<
56    H,
57    #[cfg(feature = "fuchsia")] T = zx::Channel,
58    #[cfg(not(feature = "fuchsia"))] T,
59>
60{
61    /// Handles a received connection request with the given handler.
62    fn on_connection(handler: &H, member: &str, server_end: T);
63}
64
65/// An adapter for a FIDL service handler.
66pub struct ServiceHandlerAdapter<S, H> {
67    handler: H,
68    _service: PhantomData<S>,
69}
70
71impl<S, H: Clone> Clone for ServiceHandlerAdapter<S, H> {
72    fn clone(&self) -> Self {
73        Self { handler: self.handler.clone(), _service: PhantomData }
74    }
75}
76
77unsafe impl<S, H> Send for ServiceHandlerAdapter<S, H> where H: Send {}
78unsafe impl<S, H> Sync for ServiceHandlerAdapter<S, H> where H: Sync {}
79
80impl<S, H> ServiceHandlerAdapter<S, H> {
81    /// Creates a new service handler from a supported handler.
82    pub fn from_untyped(handler: H) -> Self {
83        Self { handler, _service: PhantomData }
84    }
85}
86
87impl<S, H, T> ServiceHandler<T> for ServiceHandlerAdapter<S, H>
88where
89    S: DispatchServiceHandler<H, T>,
90{
91    fn on_connection(&self, member: &str, server_end: T) {
92        S::on_connection(&self.handler, member, server_end)
93    }
94}