1use super::*;
3use std::os::raw::c_int;
4use std::{
5 fmt, error
6};
7
8macro_rules! opaque {
9 ($obj:expr => $msg:literal $(, $args:expr)*) => {
10 {
11 #[derive(Debug)]
12 struct Opaque<'a, T: ?Sized + ::std::fmt::Debug>(::std::fmt::FormatArgs<'a>, T);
13 impl<'a, T: ?Sized + ::std::fmt::Debug> ::std::fmt::Display for Opaque<T>
14 {
15 #[inline]
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
17 {
18 use ::std::fmt::Write;
19 write!(f, "{}: {:?}", self.0, &self.1)
20 }
21 }
22 impl<'a, T: ?Sized + ::std::fmt::Debug> error::Error for Opaque<'a, T>{}
23
24 Opaque(::std::format_args!($msg, $(, $args)*), $obj)
25 }
26 };
27}
28pub(crate) use opaque;
29
30macro_rules! os_error {
32 ($fmt:literal $(, $args:expr)*) => {
33 {
34 #[derive(Debug)]
35 struct AdHoc<'a>(::std::fmt::Arguments<'a>);
36 impl<'a> ::std::fmt::Display for AdHoc<'a>
37 {
38 #[inline]
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
40 {
41 write!(f, "{}", self.0)
42 }
43 }
44 $crate::err::WrappedOSError::last_os_error(AdHoc(::std::format_args!($fmt $(, $args)*)))
45 }
46 };
47 ($(#[$outer:meta])* $vis:vis struct $name:ident => $fmt:literal $(; $($rest:tt)*)?) => {
48
49 $(#[$outer])*
50 #[derive(Debug)]
51 #[repr(transparent)]
52 $vis struct $name($crate::err::WrappedOSError<&'static str>);
53
54 impl ::std::fmt::Display for $name
55 {
56 #[inline]
57 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> fmt::Result
58 {
59 f.write_str($fmt)
60 }
61 }
62 impl ::std::error::Error for $name {
63 #[inline]
64 fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)>
65 {
66 self.0.source()
67 }
68 }
69
70 #[allow(unused)]
71 impl $name {
72 #[inline(always)]
73 fn new() -> Self
74 {
75 Self($crate::err::WrappedOSError::last_os_error($fmt))
76 }
77 #[inline(always)]
78 fn into_inner(self) -> $crate::err::WrappedOSError<&'static str>
79 {
80 self.0
81 }
82 }
83 impl ::std::ops::Deref for $name {
84 type Target = $crate::err::WrappedOSError<&'static str>;
85 #[inline]
86 fn deref(&self) -> &Self::Target
87 {
88 &self.0
89 }
90 }
91 impl ::std::ops::DerefMut for $name {
92 #[inline]
93 fn deref_mut(&mut self) -> &mut Self::Target
94 {
95 &mut self.0
96 }
97 }
98
99 $(
100 $crate::os_error! {
101 $($rest)*
102 }
103 )?
104 };
105 () => {};
106}
107pub(crate) use os_error;
108
109const _: () = {
110 os_error!(struct Test => "Test error");
111 const fn t<E: ?Sized + error::Error>() {}
112 fn r<E: ?Sized + error::Error>(_: &E) {}
113 fn test() {
114 r(&os_error!("Some error message"));
115 }
116 t::<Test>()
117};
118
119pub struct WrappedOSError<E: ?Sized>(io::Error, E);
121
122impl<E: fmt::Debug> WrappedOSError<E>
123{
124 pub(crate) fn last_os_error(ctx: E) -> Self
125 {
126 Self(io::Error::last_os_error(), ctx)
127 }
128
129 pub(crate) fn from_os_error(raw: c_int, ctx: E) -> Self
130 {
131 Self(io::Error::from_raw_os_error(raw), ctx)
132 }
133}
134
135impl<E: ?Sized> WrappedOSError<E>
136{
137 #[inline]
138 pub fn error(&self) -> &io::Error
139 {
140 &self.0
141 }
142 #[inline]
143 pub fn raw_error(&self) -> c_int
144 {
145 self.0.raw_os_error().unwrap()
146 }
147 #[inline]
148 pub fn context(&self) -> &E
149 {
150 &self.1
151 }
152}
153
154impl<E> From<WrappedOSError<E>> for io::Error
155{
156 #[inline]
157 fn from(from: WrappedOSError<E>) -> Self
158 {
159 from.0
160 }
161}
162
163
164impl<E: ?Sized> error::Error for WrappedOSError<E>
165where WrappedOSError<E>: fmt::Display + fmt::Debug
166{
167 #[inline]
168 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
169 Some(&self.0)
170 }
171}
172
173impl<E: ?Sized> fmt::Display for WrappedOSError<E>
174where E: fmt::Debug
175{
176 #[inline]
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
178 {
179 write!(f, "{:?}", &self.1)
180 }
181}
182impl<E: ?Sized> fmt::Debug for WrappedOSError<E>
183where E: fmt::Display
184{
185 #[inline]
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
187 {
188 write!(f, "{}", &self.1)
189 }
190}
191
192