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