Skip to main content

thedes_tui_core/audio/
device.rs

1use std::{borrow::Cow, fmt, io};
2
3use thiserror::Error;
4
5pub mod null;
6pub mod native;
7pub mod mock;
8
9#[derive(Debug, Error)]
10pub enum PlayNowError {
11    #[error("Failed to decode audio: {0}")]
12    Decode(String),
13    #[error("I/O error playing audio")]
14    Io(#[from] io::Error),
15}
16
17#[derive(Debug, Error)]
18pub enum SetVolumeError {
19    #[error("I/O error setting volume")]
20    Io(#[from] io::Error),
21}
22
23#[derive(Debug, Error)]
24pub enum ClearSinkError {
25    #[error("I/O error clearing the sink")]
26    Io(#[from] io::Error),
27}
28
29#[derive(Debug, Error)]
30pub enum PauseSinkError {
31    #[error("I/O error pausing the sink")]
32    Io(#[from] io::Error),
33}
34
35#[derive(Debug, Error)]
36pub enum ResumeSinkError {
37    #[error("I/O error resuming the sink")]
38    Io(#[from] io::Error),
39}
40
41#[derive(Debug, Error)]
42pub enum CheckPlayStatusError {
43    #[error("I/O error checking playing status")]
44    Io(#[from] io::Error),
45}
46
47#[derive(Debug, Error)]
48pub enum OpenSinkError {
49    #[error("I/O error opening sink")]
50    Io(#[from] io::Error),
51    #[error("Failed to manipulate audio stream: {0}")]
52    Stream(String),
53}
54
55pub trait AudioDevice: fmt::Debug + Send + Sync {
56    fn open_sink(&mut self) -> Result<Box<dyn AudioSinkDevice>, OpenSinkError>;
57}
58
59impl<'a, A> AudioDevice for &'a mut A
60where
61    A: AudioDevice + ?Sized,
62{
63    fn open_sink(&mut self) -> Result<Box<dyn AudioSinkDevice>, OpenSinkError> {
64        (**self).open_sink()
65    }
66}
67
68impl<A> AudioDevice for Box<A>
69where
70    A: AudioDevice + ?Sized,
71{
72    fn open_sink(&mut self) -> Result<Box<dyn AudioSinkDevice>, OpenSinkError> {
73        (**self).open_sink()
74    }
75}
76
77pub trait AudioSinkDevice: fmt::Debug + Send + Sync {
78    fn play_now(
79        &mut self,
80        bytes: Cow<'static, [u8]>,
81    ) -> Result<(), PlayNowError>;
82
83    fn set_volume(&mut self, volume: f32) -> Result<(), SetVolumeError>;
84
85    fn pause(&mut self) -> Result<(), PauseSinkError>;
86
87    fn resume(&mut self) -> Result<(), ResumeSinkError>;
88
89    fn clear(&mut self) -> Result<(), ClearSinkError>;
90
91    fn is_playing(&self) -> Result<bool, CheckPlayStatusError>;
92}
93
94impl<'a, S> AudioSinkDevice for &'a mut S
95where
96    S: AudioSinkDevice + ?Sized,
97{
98    fn play_now(
99        &mut self,
100        bytes: Cow<'static, [u8]>,
101    ) -> Result<(), PlayNowError> {
102        (**self).play_now(bytes)
103    }
104
105    fn set_volume(&mut self, volume: f32) -> Result<(), SetVolumeError> {
106        (**self).set_volume(volume)
107    }
108
109    fn pause(&mut self) -> Result<(), PauseSinkError> {
110        (**self).pause()
111    }
112
113    fn resume(&mut self) -> Result<(), ResumeSinkError> {
114        (**self).resume()
115    }
116
117    fn clear(&mut self) -> Result<(), ClearSinkError> {
118        (**self).clear()
119    }
120
121    fn is_playing(&self) -> Result<bool, CheckPlayStatusError> {
122        (**self).is_playing()
123    }
124}
125
126impl<S> AudioSinkDevice for Box<S>
127where
128    S: AudioSinkDevice + ?Sized,
129{
130    fn play_now(
131        &mut self,
132        bytes: Cow<'static, [u8]>,
133    ) -> Result<(), PlayNowError> {
134        (**self).play_now(bytes)
135    }
136
137    fn set_volume(&mut self, volume: f32) -> Result<(), SetVolumeError> {
138        (**self).set_volume(volume)
139    }
140
141    fn pause(&mut self) -> Result<(), PauseSinkError> {
142        (**self).pause()
143    }
144
145    fn resume(&mut self) -> Result<(), ResumeSinkError> {
146        (**self).resume()
147    }
148
149    fn clear(&mut self) -> Result<(), ClearSinkError> {
150        (**self).clear()
151    }
152
153    fn is_playing(&self) -> Result<bool, CheckPlayStatusError> {
154        (**self).is_playing()
155    }
156}