Skip to main content

ventana_hal/
backend.rs

1use {
2  crate::{
3    error::RequestError,
4    monitor::BackendMonitor,
5    settings::WindowSettings,
6    window::BackendWindow,
7  },
8  std::{
9    collections::VecDeque,
10    sync::Arc,
11  },
12};
13
14///
15/// The primary backend trait.
16///
17/// This interface allows backends to be implemented for multiple platforms. Each backend should implement every function,
18/// but default implementations are provided that return `RequestError::NotSupported` so that cfg attributes can be used
19/// to avoid compiling code for unsupported platforms.
20///
21pub trait Backend: Send + Sync {
22  /// This should return a reference to a static instance of the backend, as opposed to creating a new instance every time.
23  /// This is because some backends may need to maintain global state.
24  /// This should also return `None` if the backend is not implemented on the current platform.
25  fn instance() -> Option<&'static Self>
26  where
27    Self: Sized + 'static,
28  {
29    None
30  }
31
32  /// Returns a reference to the instance as `dyn Backend`
33  fn backend() -> Option<&'static dyn Backend>
34  where
35    Self: Sized + 'static,
36  {
37    Self::instance().map(|b| b as _)
38  }
39
40  /// This should be a quick check to see if the backend is available on the current platform. One should implement this with
41  /// compile-time cfg checks and env var checks as necessary. Then, use cfgs to avoid compiling the methods of the backend if
42  /// it is not available.
43  ///
44  /// For now this is unused, but in the future, this will be used to determine which backend to use when `Backend::auto()`
45  /// is called.
46  fn is_available() -> bool
47  where
48    Self: Sized,
49  {
50    false
51  }
52
53  /// The name of the backend, used for logging and debugging purposes.
54  fn name(&self) -> &'static str;
55
56  fn create_window(&self, settings: WindowSettings) -> Result<Arc<dyn BackendWindow>, RequestError> {
57    let _ = settings;
58    Err(RequestError::not_supported(format!("`{}` backend is not available to create a window", self.name())))
59  }
60
61  fn list_available_monitors(&self) -> Result<VecDeque<Arc<dyn BackendMonitor>>, RequestError> {
62    Err(RequestError::not_supported(format!(
63      "`{}` backend is not available to list available monitors",
64      self.name()
65    )))
66  }
67
68  fn primary_monitor(&self) -> Result<Arc<dyn BackendMonitor>, RequestError> {
69    Err(RequestError::not_supported(format!(
70      "`{}` backend is not available to get the primary monitor",
71      self.name()
72    )))
73  }
74}