[rust][vfs] Reduce monomorphization of test functions
Test: no behavioral change
Change-Id: I479a2d06b3b25522b74540981b5fdf4692c96f37
diff --git a/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/common.rs b/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/common.rs
index efe6d54..76415fa 100644
--- a/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/common.rs
+++ b/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/common.rs
@@ -11,8 +11,13 @@
OPEN_FLAG_NODE_REFERENCE, OPEN_RIGHT_ADMIN, OPEN_RIGHT_READABLE, OPEN_RIGHT_WRITABLE,
},
fuchsia_zircon::Status,
+ std::{future::Future, pin::Pin},
};
+/// A dynamically-dispatched asynchronous function.
+pub(crate) type AsyncFnOnce<'a, ArgTy, OutputTy> =
+ Box<dyn FnOnce(ArgTy) -> Pin<Box<dyn Future<Output = OutputTy> + 'a>> + 'a>;
+
/// Set of known rights.
const FS_RIGHTS: u32 = OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE | OPEN_RIGHT_ADMIN;
diff --git a/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/directory/test_utils.rs b/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/directory/test_utils.rs
index 52e85ee..e6d5ab88 100644
--- a/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/directory/test_utils.rs
+++ b/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/directory/test_utils.rs
@@ -22,7 +22,7 @@
}
use {
- crate::directory::entry::DirectoryEntry,
+ crate::{common::AsyncFnOnce, directory::entry::DirectoryEntry},
byteorder::{LittleEndian, WriteBytesExt},
fidl::endpoints::{create_proxy, ServerEnd},
fidl_fuchsia_io::{DirectoryMarker, DirectoryProxy, MAX_FILENAME},
@@ -96,13 +96,32 @@
pub fn run_server_client_with_mode_and_executor<GetClientRes>(
flags: u32,
mode: u32,
- mut exec: Executor,
- mut server: impl DirectoryEntry,
+ exec: Executor,
+ server: impl DirectoryEntry,
get_client: impl FnOnce(DirectoryProxy) -> GetClientRes,
- executor: impl FnOnce(&mut FnMut(bool) -> ()),
+ executor: impl FnOnce(&mut dyn FnMut(bool)),
) where
GetClientRes: Future<Output = ()>,
{
+ run_server_client_with_mode_and_executor_dyn(
+ flags,
+ mode,
+ exec,
+ Box::new(server),
+ Box::new(|proxy| Box::pin(get_client(proxy))),
+ Box::new(executor),
+ )
+}
+
+// helper to prevent unnecessary monomorphization
+fn run_server_client_with_mode_and_executor_dyn<'a>(
+ flags: u32,
+ mode: u32,
+ mut exec: Executor,
+ mut server: Box<dyn DirectoryEntry + 'a>,
+ get_client: AsyncFnOnce<'a, DirectoryProxy, ()>,
+ executor: Box<dyn FnOnce(&mut dyn FnMut(bool)) + 'a>,
+) {
let (client_proxy, server_end) =
create_proxy::<DirectoryMarker>().expect("Failed to create connection endpoints");
@@ -152,6 +171,9 @@
pub type OpenRequestArgs<'path> =
(u32, u32, Box<Iterator<Item = &'path str>>, ServerEnd<DirectoryMarker>);
+/// The sender end of a channel to proxy open requests.
+pub type OpenRequestSender<'path> = mpsc::Sender<OpenRequestArgs<'path>>;
+
/// Similar to [`run_server_client()`] but does not automatically connect the server and the client
/// code. Instead the client receives a sender end of an [`OpenRequestArgs`] queue, capable of
/// receiving arguments for the `open()` calls on the server. This way the client can control when
@@ -160,7 +182,7 @@
/// server is to `clone()` the existing one, which might be undesirable for a particular test.
pub fn run_server_client_with_open_requests_channel<'path, GetClientRes>(
server: impl DirectoryEntry,
- get_client: impl FnOnce(mpsc::Sender<OpenRequestArgs<'path>>) -> GetClientRes,
+ get_client: impl FnOnce(OpenRequestSender<'path>) -> GetClientRes,
) where
GetClientRes: Future<Output = ()>,
{
@@ -191,13 +213,28 @@
/// The server is wrapped in an async block that returns if it's `is_terminated` method returns
/// true.
pub fn run_server_client_with_open_requests_channel_and_executor<'path, GetClientRes>(
- mut exec: Executor,
- mut server: impl DirectoryEntry,
- get_client: impl FnOnce(mpsc::Sender<OpenRequestArgs<'path>>) -> GetClientRes,
- executor: impl FnOnce(&mut FnMut(bool) -> ()),
+ exec: Executor,
+ server: impl DirectoryEntry,
+ get_client: impl FnOnce(OpenRequestSender<'path>) -> GetClientRes,
+ executor: impl FnOnce(&mut dyn FnMut(bool)),
) where
GetClientRes: Future<Output = ()>,
{
+ run_server_client_with_open_requests_channel_and_executor_dyn(
+ exec,
+ Box::new(server),
+ Box::new(|sender| Box::pin(get_client(sender))),
+ Box::new(executor),
+ )
+}
+
+// helper to prevent monomorphization
+fn run_server_client_with_open_requests_channel_and_executor_dyn<'a, 'path: 'a>(
+ mut exec: Executor,
+ mut server: Box<dyn DirectoryEntry + 'a>,
+ get_client: AsyncFnOnce<'a, OpenRequestSender<'path>, ()>,
+ executor: Box<dyn FnOnce(&mut dyn FnMut(bool)) + 'a>,
+) {
let (open_requests_tx, open_requests_rx) = mpsc::channel::<OpenRequestArgs<'path>>(0);
let server_wrapper = async move {
diff --git a/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/file/test_utils.rs b/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/file/test_utils.rs
index 6182acc..a0ad611 100644
--- a/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/file/test_utils.rs
+++ b/garnet/public/rust/fuchsia-vfs/pseudo-fs/src/file/test_utils.rs
@@ -9,7 +9,7 @@
//! instead of `await!(assert_something(arg))`.
use {
- crate::directory::entry::DirectoryEntry,
+ crate::{common::AsyncFnOnce, directory::entry::DirectoryEntry},
fidl::endpoints::{create_proxy, ServerEnd},
fidl_fuchsia_io::{FileMarker, FileProxy},
fuchsia_async::Executor,
@@ -82,13 +82,32 @@
pub fn run_server_client_with_mode_and_executor<GetClientRes>(
flags: u32,
mode: u32,
- mut exec: Executor,
- mut server: impl DirectoryEntry,
+ exec: Executor,
+ server: impl DirectoryEntry,
get_client: impl FnOnce(FileProxy) -> GetClientRes,
- executor: impl FnOnce(&mut FnMut(bool) -> ()),
+ executor: impl FnOnce(&mut dyn FnMut(bool)),
) where
GetClientRes: Future<Output = ()>,
{
+ run_server_client_with_mode_and_executor_dyn(
+ flags,
+ mode,
+ exec,
+ Box::new(server),
+ Box::new(|proxy| Box::pin(get_client(proxy))),
+ Box::new(executor),
+ )
+}
+
+// helper to avoid monomorphization
+fn run_server_client_with_mode_and_executor_dyn<'a>(
+ flags: u32,
+ mode: u32,
+ mut exec: Executor,
+ mut server: Box<dyn DirectoryEntry + 'a>,
+ get_client: AsyncFnOnce<'a, FileProxy, ()>,
+ executor: Box<dyn FnOnce(&mut dyn FnMut(bool)) + 'a>,
+) {
let (client_proxy, server_end) =
create_proxy::<FileMarker>().expect("Failed to create connection endpoints");
@@ -137,6 +156,9 @@
/// Holds arguments for a [`DirectoryEntry::open()`] call, assuming empty path.
pub type OpenRequestArgs = (u32, u32, ServerEnd<FileMarker>);
+/// The sender end of a channel to proxy open requests.
+pub type OpenRequestSender = mpsc::Sender<OpenRequestArgs>;
+
/// Similar to [`run_server_client()`] but does not automatically connect the server and the client
/// code. Instead the client receives a sender end of an [`OpenRequestArgs`] queue, capable of
/// receiving arguments for the `open()` calls on the server. This way the client can control when
@@ -145,7 +167,7 @@
/// server is to `clone()` the existing one, which might be undesirable for a particular test.
pub fn run_server_client_with_open_requests_channel<GetClientRes>(
server: impl DirectoryEntry,
- get_client: impl FnOnce(mpsc::Sender<OpenRequestArgs>) -> GetClientRes,
+ get_client: impl FnOnce(OpenRequestSender) -> GetClientRes,
) where
GetClientRes: Future<Output = ()>,
{
@@ -177,13 +199,28 @@
///
/// See [`file::simple::mock_directory_with_one_file_and_two_connections`] for a usage example.
pub fn run_server_client_with_open_requests_channel_and_executor<GetClientRes>(
- mut exec: Executor,
- mut server: impl DirectoryEntry,
- get_client: impl FnOnce(mpsc::Sender<OpenRequestArgs>) -> GetClientRes,
- executor: impl FnOnce(&mut FnMut(bool) -> ()),
+ exec: Executor,
+ server: impl DirectoryEntry,
+ get_client: impl FnOnce(OpenRequestSender) -> GetClientRes,
+ executor: impl FnOnce(&mut FnMut(bool)),
) where
GetClientRes: Future<Output = ()>,
{
+ run_server_client_with_open_requests_channel_and_executor_dyn(
+ exec,
+ Box::new(server),
+ Box::new(|sender| Box::pin(get_client(sender))),
+ Box::new(executor),
+ )
+}
+
+// helper to avoid monomorphization
+fn run_server_client_with_open_requests_channel_and_executor_dyn<'a>(
+ mut exec: Executor,
+ mut server: Box<dyn DirectoryEntry + 'a>,
+ get_client: AsyncFnOnce<'a, OpenRequestSender, ()>,
+ executor: Box<dyn FnOnce(&mut dyn FnMut(bool)) + 'a>,
+) {
let (open_requests_tx, open_requests_rx) = mpsc::channel::<OpenRequestArgs>(0);
let server_wrapper = async move {