Skip to main content

input_pipeline_dso/
incoming.rs

1// Copyright 2026 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 crate::Transport;
6use anyhow::Context;
7use fidl_fuchsia_io as fio;
8use fuchsia_component::client::Connect;
9use fuchsia_component::directory::{AsRefDirectory, Directory};
10
11#[cfg(feature = "dso")]
12pub use dso::*;
13
14#[cfg(not(feature = "dso"))]
15pub use elf::*;
16
17impl Incoming {
18    pub fn connect_protocol_at<T: Connect>(
19        dir: &impl AsRefDirectory,
20        path: &str,
21    ) -> Result<T, anyhow::Error> {
22        T::connect_at_dir_root_with_name(dir, path).context("connect_protocol_at")
23    }
24}
25
26mod dso {
27    #![cfg(feature = "dso")]
28
29    use super::*;
30
31    #[derive(Clone)]
32    pub struct Incoming(std::sync::Arc<fdf_component::Incoming>);
33
34    impl Incoming {
35        pub fn new(incoming: std::sync::Arc<fdf_component::Incoming>) -> Self {
36            Self(incoming)
37        }
38
39        pub fn connect_protocol<T: Connect>(&self) -> Result<T, anyhow::Error> {
40            self.0.connect_protocol().context("connect_protocol")
41        }
42
43        pub fn connect_protocol_next<P: fidl_next::Discoverable>(
44            &self,
45        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
46            self.0.connect_protocol_next().context("connect_protocol_next")
47        }
48
49        pub fn connect_protocol_next_at<P: fidl_next::Discoverable>(
50            dir: &impl AsRefDirectory,
51            path: &str,
52        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
53            fdf_component::Incoming::connect_protocol_next_at(dir, path)
54                .context("connect_protocol_next_at")
55        }
56    }
57
58    impl Directory for Incoming {
59        fn open(
60            &self,
61            path: &str,
62            flags: fio::Flags,
63            server_end: zx::Channel,
64        ) -> Result<(), anyhow::Error> {
65            self.0.open(path, flags, server_end)
66        }
67    }
68}
69
70mod elf {
71    #![cfg(not(feature = "dso"))]
72
73    use super::*;
74    use fuchsia_component::client::connect;
75
76    #[derive(Clone)]
77    pub struct Incoming;
78
79    impl Incoming {
80        pub fn new() -> Self {
81            Self {}
82        }
83
84        pub fn connect_protocol<T: Connect>(&self) -> Result<T, anyhow::Error> {
85            connect::connect_to_protocol::<T>()
86        }
87
88        pub fn connect_protocol_next<P: fidl_next::Discoverable>(
89            &self,
90        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
91            let (client_end, server_end) = zx::Channel::create();
92            fdio::service_connect(&format!("/svc/{}", P::PROTOCOL_NAME), server_end)
93                .context("connect_protocol_next")?;
94            Ok(fidl_next::ClientEnd::<P, zx::Channel>::from_untyped(client_end))
95        }
96
97        pub fn connect_protocol_next_at<P: fidl_next::Discoverable>(
98            dir: &impl AsRefDirectory,
99            path: &str,
100        ) -> Result<fidl_next::ClientEnd<P, Transport>, anyhow::Error> {
101            let (client_end, server_end) = zx::Channel::create();
102            dir.as_ref_directory().open(path, fio::Flags::PROTOCOL_SERVICE, server_end)?;
103            Ok(fidl_next::ClientEnd::<P, zx::Channel>::from_untyped(client_end))
104        }
105    }
106
107    impl Directory for Incoming {
108        fn open(
109            &self,
110            path: &str,
111            flags: fio::Flags,
112            server_end: zx::Channel,
113        ) -> Result<(), anyhow::Error> {
114            fdio::open(path, flags, server_end).context("Directory::open")
115        }
116    }
117}
118
119impl AsRefDirectory for Incoming {
120    fn as_ref_directory(&self) -> &dyn fuchsia_component::directory::Directory {
121        self
122    }
123}