diff --git a/src/error.rs b/src/error.rs index f84c649d..1fd8ba21 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,6 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use std::error::Error; +use std::fmt; use std::num::NonZeroU32; use thiserror::Error; @@ -39,16 +40,41 @@ pub enum SoftBufferError { PlatformError(Option, Option>), } -#[allow(unused)] // This isn't used on all platforms -pub(crate) fn unwrap( - res: Result, - str: &str, -) -> Result { - match res { - Ok(t) => Ok(t), - Err(e) => Err(SoftBufferError::PlatformError( - Some(str.into()), - Some(Box::new(e)), - )), +/// Convenient wrapper to cast errors into SoftBufferError. +pub(crate) trait SwResultExt { + fn swbuf_err(self, msg: impl Into) -> Result; +} + +impl SwResultExt for Result { + fn swbuf_err(self, msg: impl Into) -> Result { + self.map_err(|e| { + SoftBufferError::PlatformError(Some(msg.into()), Some(Box::new(LibraryError(e)))) + }) } } + +impl SwResultExt for Option { + fn swbuf_err(self, msg: impl Into) -> Result { + self.ok_or_else(|| SoftBufferError::PlatformError(Some(msg.into()), None)) + } +} + +/// A wrapper around a library error. +/// +/// This prevents `x11-dl` and `x11rb` from becoming public dependencies, since users cannot downcast +/// to this type. +struct LibraryError(E); + +impl fmt::Debug for LibraryError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.0, f) + } +} + +impl fmt::Display for LibraryError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + +impl std::error::Error for LibraryError {} diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 2b95fd6f..2550e249 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -1,4 +1,4 @@ -use crate::{error::unwrap, util, SoftBufferError}; +use crate::{error::SwResultExt, util, SoftBufferError}; use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle}; use std::{ cell::RefCell, @@ -29,15 +29,12 @@ impl WaylandDisplayImpl { // SAFETY: Ensured by user let backend = unsafe { Backend::from_foreign_display(display_handle.display as *mut _) }; let conn = Connection::from_backend(backend); - let (globals, event_queue) = unwrap( - registry_queue_init(&conn), - "Failed to make round trip to server", - )?; + let (globals, event_queue) = + registry_queue_init(&conn).swbuf_err("Failed to make round trip to server")?; let qh = event_queue.handle(); - let shm: wl_shm::WlShm = unwrap( - globals.bind(&qh, 1..=1, ()), - "Failed to instantiate Wayland Shm", - )?; + let shm: wl_shm::WlShm = globals + .bind(&qh, 1..=1, ()) + .swbuf_err("Failed to instantiate Wayland Shm")?; Ok(Self { conn, event_queue: RefCell::new(event_queue), @@ -60,19 +57,15 @@ impl WaylandImpl { display: Rc, ) -> Result { // SAFETY: Ensured by user - let surface_id = unwrap( - unsafe { - ObjectId::from_ptr( - wl_surface::WlSurface::interface(), - window_handle.surface as _, - ) - }, - "Failed to create proxy for surface ID.", - )?; - let surface = unwrap( - wl_surface::WlSurface::from_id(&display.conn, surface_id), - "Failed to create proxy for surface ID.", - )?; + let surface_id = unsafe { + ObjectId::from_ptr( + wl_surface::WlSurface::interface(), + window_handle.surface as _, + ) + } + .swbuf_err("Failed to create proxy for surface ID.")?; + let surface = wl_surface::WlSurface::from_id(&display.conn, surface_id) + .swbuf_err("Failed to create proxy for surface ID.")?; Ok(Self { display, surface, diff --git a/src/web.rs b/src/web.rs index 9f371960..c8286d12 100644 --- a/src/web.rs +++ b/src/web.rs @@ -8,6 +8,7 @@ use web_sys::CanvasRenderingContext2d; use web_sys::HtmlCanvasElement; use web_sys::ImageData; +use crate::error::SwResultExt; use crate::SoftBufferError; use std::convert::TryInto; use std::num::NonZeroU32; @@ -22,19 +23,9 @@ pub struct WebDisplayImpl { impl WebDisplayImpl { pub(super) fn new() -> Result { let document = web_sys::window() - .ok_or_else(|| { - SoftBufferError::PlatformError( - Some("`window` is not present in this runtime".into()), - None, - ) - })? + .swbuf_err("`window` is not present in this runtime")? .document() - .ok_or_else(|| { - SoftBufferError::PlatformError( - Some("`document` is not present in this runtime".into()), - None, - ) - })?; + .swbuf_err("`document` is not present in this runtime")?; Ok(Self { document }) } @@ -61,31 +52,19 @@ impl WebImpl { .query_selector(&format!("canvas[data-raw-handle=\"{}\"]", handle.id)) // `querySelector` only throws an error if the selector is invalid. .unwrap() - .ok_or_else(|| { - SoftBufferError::PlatformError( - Some("No canvas found with the given id".into()), - None, - ) - })? + .swbuf_err("No canvas found with the given id")? // We already made sure this was a canvas in `querySelector`. .unchecked_into(); let ctx = canvas - .get_context("2d") - .map_err(|_| { - SoftBufferError::PlatformError( - Some("Canvas already controlled using `OffscreenCanvas`".into()), - None, - ) - })? - .ok_or_else(|| { - SoftBufferError::PlatformError( - Some("A canvas context other than `CanvasRenderingContext2d` was already created".into()), - None, - ) - })? - .dyn_into() - .expect("`getContext(\"2d\") didn't return a `CanvasRenderingContext2d`"); + .get_context("2d") + .ok() + .swbuf_err("Canvas already controlled using `OffscreenCanvas`")? + .swbuf_err( + "A canvas context other than `CanvasRenderingContext2d` was already created", + )? + .dyn_into() + .expect("`getContext(\"2d\") didn't return a `CanvasRenderingContext2d`"); Ok(Self { canvas, diff --git a/src/x11.rs b/src/x11.rs index 1f5386f7..f180b466 100644 --- a/src/x11.rs +++ b/src/x11.rs @@ -5,6 +5,7 @@ #![allow(clippy::uninlined_format_args)] +use crate::error::SwResultExt; use crate::{util, SoftBufferError}; use nix::libc::{shmat, shmctl, shmdt, shmget, IPC_PRIVATE, IPC_RMID}; use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle}; @@ -650,19 +651,6 @@ impl From for PushBufferError { } } -/// Convenient wrapper to cast errors into SoftBufferError. -trait SwResultExt { - fn swbuf_err(self, msg: impl Into) -> Result; -} - -impl SwResultExt for Result { - fn swbuf_err(self, msg: impl Into) -> Result { - self.map_err(|e| { - SoftBufferError::PlatformError(Some(msg.into()), Some(Box::new(LibraryError(e)))) - }) - } -} - /// Convenient wrapper to cast errors into PushBufferError. trait PushResultExt { fn push_err(self) -> Result; @@ -674,26 +662,6 @@ impl> PushResultExt for Result { } } -/// A wrapper around a library error. -/// -/// This prevents `x11-dl` and `x11rb` from becoming public dependencies, since users cannot downcast -/// to this type. -struct LibraryError(E); - -impl fmt::Debug for LibraryError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.0, f) - } -} - -impl fmt::Display for LibraryError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, f) - } -} - -impl std::error::Error for LibraryError {} - /// Get the length that a slice needs to be to hold a buffer of the given dimensions. #[inline(always)] fn total_len(width: u16, height: u16) -> usize {