mapped_file/
err.rs

1//! Wrapping `errno` error types
2use 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
30/// Construct an ad-hoc error wrapping the last OS error.
31macro_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
119/// Wraps a piece of context over an OS error
120pub 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