1use std::{io, fmt::Display, error, sync::PoisonError};
4
5use crate::cpal_abstraction::SampleType;
6
7pub type Error<T> = Result<T, PlayError>;
9
10#[derive(Debug)]
11pub enum PlayError {
13 TimeOutOfBounds,
15 FileNotAccessible(io::Error),
17 WrongFileType,
19 DeviceIoError(String, Option<Box<dyn error::Error + 'static>>),
21 DeviceDoesNotSupportAudioSettings(Vec<AudioSettings>, Option<Box<dyn error::Error + 'static>>),
23 DeviceDoesNotExist{
25 name: String
27 },
28 StreamIoError(String, Option<Box<dyn error::Error + 'static>>),
30 PoisonedMutex(String, Box<dyn error::Error>),
32 Unsupported(String),
34}
35
36impl Display for PlayError {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 match self {
39 Self::TimeOutOfBounds => f.write_str("the time specified is out of bounds"),
40 Self::FileNotAccessible(_) => f.write_str("there was an error while trying to access the file"),
41 Self::WrongFileType => f.write_str("file was of the wrong file type"),
42 Self::DeviceDoesNotExist{ name: n } => f.write_str(&format!("the device '{n}' does not exist")),
43 Self::DeviceIoError(c, _) => f.write_str(&format!("the device had an issue with io because {c}")),
44 Self::DeviceDoesNotSupportAudioSettings(s, _) => f.write_str(&format!("the device had an issue with config because {s:?} is/are not supported")),
45 Self::StreamIoError(s, _) => f.write_str(&format!("error while communicating with stream: {s}")),
46 Self::PoisonedMutex(s, _) => f.write_str(&format!("error while trying to access mutex {s}")),
47 Self::Unsupported(e) => f.write_str(&format!("ez_audi does not support '{}'", e)),
48 }
49 }
50}
51
52impl error::Error for PlayError {
53 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
54 match self {
55 Self::TimeOutOfBounds => None,
56 Self::FileNotAccessible(e) => Some(e),
57 Self::WrongFileType => None,
58 Self::DeviceDoesNotExist{ .. } => None,
59 Self::DeviceIoError(_, s) => {
60 match s {
61 Some(s) => Some(&**s.clone()),
62 None => None,
63 }
64 },
65 Self::DeviceDoesNotSupportAudioSettings(_, s) => {
66 match s {
67 Some(s) => Some(&**s.clone()),
68 None => None,
69 }
70 },
71 Self::StreamIoError(_, s) => {
72 match s {
73 Some(s) => Some(&**s.clone()),
74 None => None,
75 }
76 },
77 Self::PoisonedMutex(_, s) => Some(&**s),
78 Self::Unsupported(_) => None,
79 }
80 }
81}
82
83impl From<io::Error> for PlayError {
84 fn from(value: io::Error) -> Self {
85 Self::FileNotAccessible(value)
86 }
87}
88
89impl From<cpal::PlayStreamError> for PlayError {
90 fn from(value: cpal::PlayStreamError) -> Self {
91 Self::StreamIoError("failed play stream".to_string(), Some(Box::new(value)))
92 }
93}
94
95impl From<cpal::PauseStreamError> for PlayError {
96 fn from(value: cpal::PauseStreamError) -> Self {
97 Self::StreamIoError("failed pause stream".to_string(), Some(Box::new(value)))
98 }
99}
100
101impl<T: 'static> From<PoisonError<T>> for PlayError {
102 fn from(value: PoisonError<T>) -> Self {
103 Self::PoisonedMutex("".to_string(), Box::new(value))
104 }
105}
106
107#[derive(Debug, Clone, PartialEq)]
108pub enum AudioSettings {
110 SampleType(Option<SampleType>),
112 SampleRate(u32),
114 Channels(u32),
116 Combinaison,
120}
121
122impl Display for AudioSettings {
123 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124 match self {
125 Self::SampleType(st) => f.write_str(&format!("the sample type {:?}", st)),
126 Self::SampleRate(r) => f.write_str(&format!("the sample rate of {:?}", r)),
127 Self::Channels(c) => f.write_str(&format!("the channel count of {:?}", c)),
128 Self::Combinaison => f.write_str("the combinaison of settings")
129 }
130 }
131}