cros_async/
audio_streams_async.rs

1// Copyright 2022 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Implements the interface required by `audio_streams` using the cros_async Executor.
6//!
7//! It implements the `AudioStreamsExecutor` trait for `Executor`, so it can be passed into
8//! the audio_streams API.
9use std::io::Result;
10#[cfg(any(target_os = "android", target_os = "linux"))]
11use std::os::unix::net::UnixStream;
12#[cfg(windows)]
13use std::os::windows::io::RawHandle;
14use std::time::Duration;
15
16use async_trait::async_trait;
17#[cfg(any(target_os = "android", target_os = "linux"))]
18use audio_streams::async_api::AsyncStream;
19use audio_streams::async_api::AudioStreamsExecutor;
20use audio_streams::async_api::EventAsyncWrapper;
21use audio_streams::async_api::ReadAsync;
22use audio_streams::async_api::ReadWriteAsync;
23use audio_streams::async_api::WriteAsync;
24#[cfg(any(target_os = "android", target_os = "linux"))]
25use base::Descriptor;
26#[cfg(windows)]
27use base::Event;
28#[cfg(windows)]
29use base::FromRawDescriptor;
30#[cfg(any(target_os = "android", target_os = "linux"))]
31use base::RawDescriptor;
32
33#[cfg(any(target_os = "android", target_os = "linux"))]
34use super::AsyncWrapper;
35use crate::EventAsync;
36use crate::IntoAsync;
37use crate::IoSource;
38use crate::TimerAsync;
39
40/// A wrapper around IoSource that is compatible with the audio_streams traits.
41pub struct IoSourceWrapper<T: IntoAsync + Send> {
42    source: IoSource<T>,
43}
44
45#[async_trait(?Send)]
46impl<T: IntoAsync + Send> ReadAsync for IoSourceWrapper<T> {
47    async fn read_to_vec<'a>(
48        &'a self,
49        file_offset: Option<u64>,
50        vec: Vec<u8>,
51    ) -> Result<(usize, Vec<u8>)> {
52        self.source
53            .read_to_vec(file_offset, vec)
54            .await
55            .map_err(Into::into)
56    }
57}
58
59#[async_trait(?Send)]
60impl<T: IntoAsync + Send> WriteAsync for IoSourceWrapper<T> {
61    async fn write_from_vec<'a>(
62        &'a self,
63        file_offset: Option<u64>,
64        vec: Vec<u8>,
65    ) -> Result<(usize, Vec<u8>)> {
66        self.source
67            .write_from_vec(file_offset, vec)
68            .await
69            .map_err(Into::into)
70    }
71}
72
73#[async_trait(?Send)]
74impl<T: IntoAsync + Send> ReadWriteAsync for IoSourceWrapper<T> {}
75
76#[async_trait(?Send)]
77impl EventAsyncWrapper for EventAsync {
78    async fn wait(&self) -> Result<u64> {
79        self.next_val().await.map_err(Into::into)
80    }
81}
82
83#[async_trait(?Send)]
84impl AudioStreamsExecutor for super::Executor {
85    #[cfg(any(target_os = "android", target_os = "linux"))]
86    fn async_unix_stream(&self, stream: UnixStream) -> Result<AsyncStream> {
87        Ok(Box::new(IoSourceWrapper {
88            source: self.async_from(AsyncWrapper::new(stream))?,
89        }))
90    }
91
92    /// # Safety
93    /// This is only safe if `event` is a handle to a Windows Event.
94    #[cfg(windows)]
95    unsafe fn async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>> {
96        Ok(Box::new(
97            EventAsync::new(Event::from_raw_descriptor(event), self)
98                .map_err(std::io::Error::from)?,
99        ))
100    }
101
102    async fn delay(&self, dur: Duration) -> Result<()> {
103        TimerAsync::sleep(self, dur).await.map_err(Into::into)
104    }
105
106    #[cfg(any(target_os = "android", target_os = "linux"))]
107    async fn wait_fd_readable(&self, fd: RawDescriptor) -> Result<()> {
108        self.async_from(AsyncWrapper::new(Descriptor(fd)))?
109            .wait_readable()
110            .await
111            .map_err(Into::into)
112    }
113}