use crate::vk;
use std::{
error::Error,
fmt::{self, Debug, Display},
};
#[must_use = "this `VulkanResult` may be an error, which should be handled"]
#[derive(Copy, Clone, Default)]
pub struct VulkanResult<T> {
pub raw: vk::Result,
pub value: Option<T>,
}
impl<T> VulkanResult<T> {
#[inline]
pub fn new(raw: vk::Result, value: T) -> VulkanResult<T> {
let value = if raw.0.is_negative() {
None
} else {
Some(value)
};
VulkanResult { raw, value }
}
#[inline]
#[track_caller]
pub fn unwrap(self) -> T {
match self.value {
Some(value) => value,
None => panic!("{:?}", self.raw),
}
}
#[inline]
#[track_caller]
pub fn expect(self, msg: impl Display) -> T {
match self.value {
Some(value) => value,
None => panic!("{:?}: {}", self.raw, msg),
}
}
#[inline]
pub fn as_ref(&self) -> VulkanResult<&T> {
VulkanResult {
raw: self.raw.clone(),
value: self.value.as_ref(),
}
}
#[inline]
pub fn as_mut(&mut self) -> VulkanResult<&mut T> {
VulkanResult {
raw: self.raw.clone(),
value: self.value.as_mut(),
}
}
#[inline]
pub fn new_ok(value: T) -> VulkanResult<T> {
VulkanResult::new(vk::Result::SUCCESS, value)
}
#[inline]
pub fn new_err(raw: vk::Result) -> VulkanResult<T> {
VulkanResult { raw, value: None }
}
#[inline]
pub fn ok(self) -> Option<T> {
self.value
}
#[inline]
pub fn result(self) -> Result<T, vk::Result> {
self.value.ok_or(self.raw)
}
#[inline]
pub fn map_err<F, O: FnOnce(vk::Result) -> F>(self, op: O) -> Result<T, F> {
let raw = self.raw;
self.value.ok_or_else(move || op(raw))
}
#[inline]
pub fn is_ok(&self) -> bool {
self.value.is_some()
}
#[inline]
pub fn raw_is_ok(&self) -> bool {
self.raw.0.is_positive()
}
#[inline]
pub fn is_err(&self) -> bool {
self.value.is_none()
}
#[inline]
pub fn raw_is_err(&self) -> bool {
self.raw.0.is_negative()
}
}
impl Display for vk::Result {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(self, fmt)
}
}
impl Error for vk::Result {}
impl<T> Debug for VulkanResult<T>
where
T: Debug,
{
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match &self.value {
Some(value) => {
write!(fmt, "{:?}: ", self.raw)?;
Debug::fmt(value, fmt)
}
None => write!(fmt, "{:?}: (no value)", self.raw),
}
}
}
impl<T> Display for VulkanResult<T>
where
T: Display,
{
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match &self.value {
Some(value) => {
write!(fmt, "{:?}: ", self.raw)?;
Display::fmt(value, fmt)
}
None => write!(fmt, "{:?}: (no value)", self.raw),
}
}
}