1use std::ffi::CStr;
17use num_traits::FromPrimitive as FromPrimitiveTrait;
18use num_derive::{FromPrimitive, ToPrimitive};
19
20#[repr(transparent)]
23#[derive(Debug, Copy, Clone, PartialEq, Eq)]
24pub struct PAErr(pub i32);
25
26#[repr(C)]
28#[derive(Debug, Copy, Clone, PartialEq, Eq)]
29#[derive(FromPrimitive, ToPrimitive)]
30#[allow(non_camel_case_types)]
31pub enum Code {
32 Ok = 0,
36 Access,
38 Command,
40 Invalid,
42 Exist,
44 NoEntity,
46 ConnectionRefused,
48 Protocol,
50 Timeout,
52 AuthKey,
54 Internal,
56 ConnectionTerminated,
58 Killed,
60 InvalidServer,
62 ModInitFailed,
64 BadState,
66 NoData,
68 Version,
70 TooLarge,
72 NotSupported,
74 Unknown,
76 NoExtension,
78 Obsolete,
80 NotImplemented,
82 Forked,
84 IO,
86 Busy,
88}
89
90#[test]
92fn code_compare_capi() {
93 assert_eq!(std::mem::size_of::<Code>(), std::mem::size_of::<capi::pa_error_code_t>());
94 assert_eq!(std::mem::align_of::<Code>(), std::mem::align_of::<capi::pa_error_code_t>());
95
96 assert_eq!(Code::Ok, Code::from(capi::pa_error_code_t::Ok));
99 assert_eq!(Code::Access, Code::from(capi::pa_error_code_t::Access));
100 assert_eq!(Code::Command, Code::from(capi::pa_error_code_t::Command));
101 assert_eq!(Code::Invalid, Code::from(capi::pa_error_code_t::Invalid));
102 assert_eq!(Code::Exist, Code::from(capi::pa_error_code_t::Exist));
103 assert_eq!(Code::NoEntity, Code::from(capi::pa_error_code_t::NoEntity));
104 assert_eq!(Code::ConnectionRefused, Code::from(capi::pa_error_code_t::ConnectionRefused));
105 assert_eq!(Code::Protocol, Code::from(capi::pa_error_code_t::Protocol));
106 assert_eq!(Code::Timeout, Code::from(capi::pa_error_code_t::Timeout));
107 assert_eq!(Code::AuthKey, Code::from(capi::pa_error_code_t::AuthKey));
108 assert_eq!(Code::Internal, Code::from(capi::pa_error_code_t::Internal));
109 assert_eq!(Code::ConnectionTerminated, Code::from(capi::pa_error_code_t::ConnectionTerminated));
110 assert_eq!(Code::Killed, Code::from(capi::pa_error_code_t::Killed));
111 assert_eq!(Code::InvalidServer, Code::from(capi::pa_error_code_t::InvalidServer));
112 assert_eq!(Code::ModInitFailed, Code::from(capi::pa_error_code_t::ModInitFailed));
113 assert_eq!(Code::BadState, Code::from(capi::pa_error_code_t::BadState));
114 assert_eq!(Code::NoData, Code::from(capi::pa_error_code_t::NoData));
115 assert_eq!(Code::Version, Code::from(capi::pa_error_code_t::Version));
116 assert_eq!(Code::TooLarge, Code::from(capi::pa_error_code_t::TooLarge));
117 assert_eq!(Code::NotSupported, Code::from(capi::pa_error_code_t::NotSupported));
118 assert_eq!(Code::Unknown, Code::from(capi::pa_error_code_t::Unknown));
119 assert_eq!(Code::NoExtension, Code::from(capi::pa_error_code_t::NoExtension));
120 assert_eq!(Code::Obsolete, Code::from(capi::pa_error_code_t::Obsolete));
121 assert_eq!(Code::NotImplemented, Code::from(capi::pa_error_code_t::NotImplemented));
122 assert_eq!(Code::Forked, Code::from(capi::pa_error_code_t::Forked));
123 assert_eq!(Code::IO, Code::from(capi::pa_error_code_t::IO));
124 assert_eq!(Code::Busy, Code::from(capi::pa_error_code_t::Busy));
125}
126
127impl From<Code> for capi::pa_error_code_t {
128 #[inline]
129 fn from(c: Code) -> Self {
130 unsafe { std::mem::transmute(c) }
131 }
132}
133impl From<capi::pa_error_code_t> for Code {
134 #[inline]
135 fn from(c: capi::pa_error_code_t) -> Self {
136 unsafe { std::mem::transmute(c) }
137 }
138}
139
140impl PAErr {
141 pub fn to_string(&self) -> Option<String> {
144 let ptr = unsafe { capi::pa_strerror(self.0) };
145 match ptr.is_null() {
146 false => Some(unsafe { CStr::from_ptr(ptr).to_string_lossy().into_owned() }),
147 true => None,
148 }
149 }
150}
151
152impl std::error::Error for PAErr {}
153
154impl std::fmt::Display for PAErr {
155 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
156 match self.to_string() {
157 Some(s) => write!(f, "{}", s),
158 None => write!(f, ""),
159 }
160 }
161}
162
163impl Code {
164 #[inline]
166 pub fn to_string(self) -> Option<String> {
167 PAErr::from(self).to_string()
168 }
169}
170
171impl std::error::Error for Code {}
172
173impl std::fmt::Display for Code {
174 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
175 match (*self).to_string() {
176 Some(s) => write!(f, "{}", s),
177 None => write!(f, ""),
178 }
179 }
180}
181
182impl From<Code> for PAErr {
183 #[inline]
184 fn from(c: Code) -> Self {
185 PAErr(-(c as i32))
187 }
188}
189
190impl TryFrom<PAErr> for Code {
191 type Error = ();
192
193 #[inline]
197 fn try_from(e: PAErr) -> Result<Self, Self::Error> {
198 let abs = -(e.0);
200 Code::from_i32(abs).ok_or(())
201 }
202}
203
204#[test]
206fn check_code_paerr_conversions() {
207 assert_eq!(Ok(Code::Ok), Code::try_from(PAErr(0)));
208 assert_eq!(Ok(Code::Access), Code::try_from(PAErr(-1)));
209 assert_eq!(Ok(Code::Command), Code::try_from(PAErr(-2)));
210 assert_eq!(Ok(Code::Invalid), Code::try_from(PAErr(-3)));
211 assert_eq!(Ok(Code::Exist), Code::try_from(PAErr(-4)));
212 assert_eq!(Ok(Code::NoEntity), Code::try_from(PAErr(-5)));
213 assert_eq!(Ok(Code::ConnectionRefused), Code::try_from(PAErr(-6)));
214 assert_eq!(Ok(Code::Protocol), Code::try_from(PAErr(-7)));
215 assert_eq!(Ok(Code::Timeout), Code::try_from(PAErr(-8)));
216 assert_eq!(Ok(Code::AuthKey), Code::try_from(PAErr(-9)));
217 assert_eq!(Ok(Code::Internal), Code::try_from(PAErr(-10)));
218 assert_eq!(Ok(Code::ConnectionTerminated), Code::try_from(PAErr(-11)));
219 assert_eq!(Ok(Code::Killed), Code::try_from(PAErr(-12)));
220 assert_eq!(Ok(Code::InvalidServer), Code::try_from(PAErr(-13)));
221 assert_eq!(Ok(Code::ModInitFailed), Code::try_from(PAErr(-14)));
222 assert_eq!(Ok(Code::BadState), Code::try_from(PAErr(-15)));
223 assert_eq!(Ok(Code::NoData), Code::try_from(PAErr(-16)));
224 assert_eq!(Ok(Code::Version), Code::try_from(PAErr(-17)));
225 assert_eq!(Ok(Code::TooLarge), Code::try_from(PAErr(-18)));
226 assert_eq!(Ok(Code::NotSupported), Code::try_from(PAErr(-19)));
227 assert_eq!(Ok(Code::Unknown), Code::try_from(PAErr(-20)));
228 assert_eq!(Ok(Code::NoExtension), Code::try_from(PAErr(-21)));
229 assert_eq!(Ok(Code::Obsolete), Code::try_from(PAErr(-22)));
230 assert_eq!(Ok(Code::NotImplemented), Code::try_from(PAErr(-23)));
231 assert_eq!(Ok(Code::Forked), Code::try_from(PAErr(-24)));
232 assert_eq!(Ok(Code::IO), Code::try_from(PAErr(-25)));
233 assert_eq!(Ok(Code::Busy), Code::try_from(PAErr(-26)));
234 assert_eq!(Err(()), Code::try_from(PAErr(-27)));
235 assert_eq!(Err(()), Code::try_from(PAErr(1)));
236
237 assert_eq!(PAErr::from(Code::Ok), PAErr(0));
238 assert_eq!(PAErr::from(Code::Access), PAErr(-1));
239 assert_eq!(PAErr::from(Code::Command), PAErr(-2));
240 assert_eq!(PAErr::from(Code::Invalid), PAErr(-3));
241 assert_eq!(PAErr::from(Code::Exist), PAErr(-4));
242 assert_eq!(PAErr::from(Code::NoEntity), PAErr(-5));
243 assert_eq!(PAErr::from(Code::ConnectionRefused), PAErr(-6));
244 assert_eq!(PAErr::from(Code::Protocol), PAErr(-7));
245 assert_eq!(PAErr::from(Code::Timeout), PAErr(-8));
246 assert_eq!(PAErr::from(Code::AuthKey), PAErr(-9));
247 assert_eq!(PAErr::from(Code::Internal), PAErr(-10));
248 assert_eq!(PAErr::from(Code::ConnectionTerminated), PAErr(-11));
249 assert_eq!(PAErr::from(Code::Killed), PAErr(-12));
250 assert_eq!(PAErr::from(Code::InvalidServer), PAErr(-13));
251 assert_eq!(PAErr::from(Code::ModInitFailed), PAErr(-14));
252 assert_eq!(PAErr::from(Code::BadState), PAErr(-15));
253 assert_eq!(PAErr::from(Code::NoData), PAErr(-16));
254 assert_eq!(PAErr::from(Code::Version), PAErr(-17));
255 assert_eq!(PAErr::from(Code::TooLarge), PAErr(-18));
256 assert_eq!(PAErr::from(Code::NotSupported), PAErr(-19));
257 assert_eq!(PAErr::from(Code::Unknown), PAErr(-20));
258 assert_eq!(PAErr::from(Code::NoExtension), PAErr(-21));
259 assert_eq!(PAErr::from(Code::Obsolete), PAErr(-22));
260 assert_eq!(PAErr::from(Code::NotImplemented), PAErr(-23));
261 assert_eq!(PAErr::from(Code::Forked), PAErr(-24));
262 assert_eq!(PAErr::from(Code::IO), PAErr(-25));
263 assert_eq!(PAErr::from(Code::Busy), PAErr(-26));
264}