use std::fmt;
#[derive(Debug)]
#[non_exhaustive]
pub enum ChunkError {
Unsupported(String),
InvalidArg(String),
Parse(String),
Io(std::io::Error),
}
impl fmt::Display for ChunkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChunkError::Unsupported(m) => write!(f, "unsupported: {m}"),
ChunkError::InvalidArg(m) => write!(f, "invalid argument: {m}"),
ChunkError::Parse(m) => write!(f, "parse error: {m}"),
ChunkError::Io(e) => write!(f, "io error: {e}"),
}
}
}
impl std::error::Error for ChunkError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ChunkError::Io(e) => Some(e),
_ => None,
}
}
}
impl From<std::io::Error> for ChunkError {
fn from(e: std::io::Error) -> Self {
ChunkError::Io(e)
}
}
impl From<String> for ChunkError {
fn from(m: String) -> Self {
ChunkError::Parse(m)
}
}
pub type Result<T> = std::result::Result<T, ChunkError>;
pub(crate) fn panic_message(payload: Box<dyn std::any::Any + Send>) -> String {
payload
.downcast_ref::<&str>()
.map(|s| (*s).to_string())
.or_else(|| payload.downcast_ref::<String>().cloned())
.unwrap_or_else(|| "unknown panic payload".to_string())
}
#[cfg(test)]
mod panic_message_tests {
use super::panic_message;
#[test]
fn stringifies_both_payload_shapes_and_neither() {
let s = std::panic::catch_unwind(|| panic!("static str")).unwrap_err();
assert_eq!(panic_message(s), "static str");
let owned = std::panic::catch_unwind(|| panic!("{}", String::from("owned"))).unwrap_err();
assert_eq!(panic_message(owned), "owned");
let odd = std::panic::catch_unwind(|| std::panic::panic_any(42u8)).unwrap_err();
assert_eq!(panic_message(odd), "unknown panic payload");
}
}