Skip to main content

ventana_hal/
error.rs

1// Taken directly from Winit under the Apache License 2.0 license https://github.com/rust-windowing/winit/blob/master/winit-core/src/error.rs
2
3use {
4  smol_str::SmolStr,
5  std::fmt::{
6    self,
7    Display,
8  },
9};
10
11/// A general error that may occur during a request to the windowing system.
12#[derive(thiserror::Error, Debug)]
13#[non_exhaustive]
14pub enum RequestError {
15  /// The request is not supported.
16  #[error("The request is not supported. `{0}`")]
17  NotSupported(SmolStr),
18  #[error("The request was ignored by the OS")]
19  Ignored,
20  /// Got unspecified OS specific error during the request.
21  #[error("OS specific error. `{0}`")]
22  Os(#[from] OsError),
23}
24
25impl RequestError {
26  pub fn not_supported(message: impl Into<SmolStr>) -> Self {
27    Self::NotSupported(message.into())
28  }
29}
30
31/// Unclassified error from the OS.
32#[derive(thiserror::Error, Debug)]
33pub struct OsError {
34  line: u32,
35  file: &'static str,
36  error: Box<dyn std::error::Error + Send + Sync + 'static>,
37}
38
39impl OsError {
40  pub fn new(
41    line: u32,
42    file: &'static str,
43    error: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
44  ) -> Self {
45    Self { line, file, error: error.into() }
46  }
47}
48
49impl Display for OsError {
50  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51    f.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error))
52  }
53}
54
55pub trait MapToOSError<T, E> {
56  fn map_to_os_err(self) -> Result<T, OsError>
57  where
58    Self: Sized;
59
60  fn request_error(self) -> Result<T, RequestError>
61  where
62    Self: Sized;
63}
64
65impl<T, E> MapToOSError<T, E> for Result<T, E>
66where
67  E: std::error::Error + Send + Sync + 'static,
68{
69  fn map_to_os_err(self) -> Result<T, OsError>
70  where
71    Self: Sized,
72  {
73    match self {
74      Ok(t) => Ok(t),
75      Err(e) => Err(crate::os_error!(e)),
76    }
77  }
78
79  fn request_error(self) -> Result<T, RequestError>
80  where
81    Self: Sized,
82  {
83    Ok(self.map_to_os_err()?)
84  }
85}
86
87#[allow(unused_macros)]
88#[macro_export]
89macro_rules! os_error {
90  ($error:expr) => {{ $crate::error::OsError::new(line!(), file!(), $error) }};
91}
92
93#[allow(unused_macros)]
94#[macro_export]
95macro_rules! os_error_fmt {
96  ($error:expr) => {{ $crate::os_error!(format!($error)) }};
97}