Skip to main content

rustc_proc_macro/bridge/
panic_message.rs

1use std::any::Any;
2
3use crate::bridge::{Buffer, Decode, Encode};
4
5/// Simplified version of panic payloads, ignoring
6/// types other than `&'static str` and `String`.
7pub enum PanicMessage {
8    StaticStr(&'static str),
9    String(String),
10    Unknown,
11}
12
13impl From<Box<dyn Any + Send>> for PanicMessage {
14    fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
15        if let Some(s) = payload.downcast_ref::<&'static str>() {
16            return PanicMessage::StaticStr(s);
17        }
18        if let Ok(s) = payload.downcast::<String>() {
19            return PanicMessage::String(*s);
20        }
21        PanicMessage::Unknown
22    }
23}
24
25impl From<PanicMessage> for Box<dyn Any + Send> {
26    fn from(val: PanicMessage) -> Self {
27        match val {
28            PanicMessage::StaticStr(s) => Box::new(s),
29            PanicMessage::String(s) => Box::new(s),
30            PanicMessage::Unknown => {
31                struct UnknownPanicMessage;
32                Box::new(UnknownPanicMessage)
33            }
34        }
35    }
36}
37
38impl PanicMessage {
39    pub fn as_str(&self) -> Option<&str> {
40        match self {
41            PanicMessage::StaticStr(s) => Some(s),
42            PanicMessage::String(s) => Some(s),
43            PanicMessage::Unknown => None,
44        }
45    }
46
47    pub fn into_string(self) -> Option<String> {
48        match self {
49            PanicMessage::StaticStr(s) => Some(s.into()),
50            PanicMessage::String(s) => Some(s),
51            PanicMessage::Unknown => None,
52        }
53    }
54}
55
56impl<S> Encode<S> for PanicMessage {
57    #[inline]
58    fn encode(self, w: &mut Buffer, s: &mut S) {
59        self.as_str().encode(w, s);
60    }
61}
62
63impl<S> Decode<'_, '_, S> for PanicMessage {
64    #[inline]
65    fn decode(r: &mut &[u8], s: &mut S) -> Self {
66        match Option::<String>::decode(r, s) {
67            Some(s) => PanicMessage::String(s),
68            None => PanicMessage::Unknown,
69        }
70    }
71}