// Copyright 2022 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. //! Implements the interface required by `audio_streams` using the cros_async Executor. //! //! It implements the `AudioStreamsExecutor` trait for `Executor`, so it can be passed into //! the audio_streams API. use std::io::Result; #[cfg(any(target_os = "android", target_os = "linux"))] use std::os::unix::net::UnixStream; #[cfg(windows)] use std::os::windows::io::RawHandle; use std::time::Duration; use async_trait::async_trait; #[cfg(any(target_os = "android", target_os = "linux"))] use audio_streams::async_api::AsyncStream; use audio_streams::async_api::AudioStreamsExecutor; use audio_streams::async_api::EventAsyncWrapper; use audio_streams::async_api::ReadAsync; use audio_streams::async_api::ReadWriteAsync; use audio_streams::async_api::WriteAsync; #[cfg(any(target_os = "android", target_os = "linux"))] use base::Descriptor; #[cfg(windows)] use base::Event; #[cfg(windows)] use base::FromRawDescriptor; #[cfg(any(target_os = "android", target_os = "linux"))] use base::RawDescriptor; #[cfg(any(target_os = "android", target_os = "linux"))] use super::AsyncWrapper; use crate::EventAsync; use crate::IntoAsync; use crate::IoSource; use crate::TimerAsync; /// A wrapper around IoSource that is compatible with the audio_streams traits. pub struct IoSourceWrapper { source: IoSource, } #[async_trait(?Send)] impl ReadAsync for IoSourceWrapper { async fn read_to_vec<'a>( &'a self, file_offset: Option, vec: Vec, ) -> Result<(usize, Vec)> { self.source .read_to_vec(file_offset, vec) .await .map_err(Into::into) } } #[async_trait(?Send)] impl WriteAsync for IoSourceWrapper { async fn write_from_vec<'a>( &'a self, file_offset: Option, vec: Vec, ) -> Result<(usize, Vec)> { self.source .write_from_vec(file_offset, vec) .await .map_err(Into::into) } } #[async_trait(?Send)] impl ReadWriteAsync for IoSourceWrapper {} #[async_trait(?Send)] impl EventAsyncWrapper for EventAsync { async fn wait(&self) -> Result { self.next_val().await.map_err(Into::into) } } #[async_trait(?Send)] impl AudioStreamsExecutor for super::Executor { #[cfg(any(target_os = "android", target_os = "linux"))] fn async_unix_stream(&self, stream: UnixStream) -> Result { Ok(Box::new(IoSourceWrapper { source: self.async_from(AsyncWrapper::new(stream))?, })) } /// # Safety /// This is only safe if `event` is a handle to a Windows Event. #[cfg(windows)] unsafe fn async_event(&self, event: RawHandle) -> Result> { Ok(Box::new( EventAsync::new(Event::from_raw_descriptor(event), self) .map_err(std::io::Error::from)?, )) } async fn delay(&self, dur: Duration) -> Result<()> { TimerAsync::sleep(self, dur).await.map_err(Into::into) } #[cfg(any(target_os = "android", target_os = "linux"))] async fn wait_fd_readable(&self, fd: RawDescriptor) -> Result<()> { self.async_from(AsyncWrapper::new(Descriptor(fd)))? .wait_readable() .await .map_err(Into::into) } }