1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
//! Provider of [`TestPanicResult`].
use std::any::Any;
/// Result of [`test_panic`](crate::test_panic::test_panic) function.
#[must_use]
#[derive(Debug)]
pub enum TestPanicResult<R> {
/// No panic result. Contains callback function result.
Cool(R),
/// Panic result. Contains panic payload.
Panic(Box<dyn Any + Send>),
}
impl<R> TestPanicResult<R> {
/// Returns `true` if self is [`Cool`](Self::Cool).
#[must_use]
pub fn is_cool(&self) -> bool {
matches!(*self, Self::Cool(_))
}
/// Returns `true` if self is [`Panic`](Self::Panic).
#[must_use]
pub fn is_panic(&self) -> bool {
matches!(*self, Self::Panic(_))
}
/// Converts `self` into success result if any.
pub fn cool(self) -> Option<R> {
match self {
Self::Cool(x) => Some(x),
Self::Panic(_) => None,
}
}
/// Converts `self` into panic payload if any.
pub fn panic(self) -> Option<Box<dyn Any + Send>> {
match self {
Self::Cool(_) => None,
Self::Panic(x) => Some(x),
}
}
/// Return result value.
///
/// # Panics
///
/// Panics if self is [`Panic`](Self::Panic).
#[must_use]
pub fn value(&self) -> &R {
match self {
Self::Cool(x) => x,
Self::Panic(_) => panic!("`self` is panic."),
}
}
/// Return panic payload.
///
/// # Panics
///
/// Panics if self is [`Cool`](Self::Cool).
#[must_use]
pub fn payload(&self) -> &Box<dyn Any + Send> {
match self {
Self::Cool(_) => panic!("`self` is cool."),
Self::Panic(x) => x,
}
}
/// Return panic payload.
///
/// # Panics
///
/// Panics if self is [`Cool`](Self::Cool) or panic payload is not
/// [`&str`] or [`String`].
#[must_use]
pub fn message(&self) -> String {
if self.is_cool() {
panic!("`self` is cool.");
}
match Self::string_like_to_string(self.payload().as_ref()) {
None => panic!("Panic payload is not string like."),
Some(x) => x,
}
}
/// Converts string like value to string.
fn string_like_to_string(any: &(dyn Any + Send)) -> Option<String> {
if let Some(x) = any.downcast_ref::<&str>() {
return Some(x.to_string());
}
if let Some(x) = any.downcast_ref::<String>() {
return Some(x.to_owned());
}
None
}
}