polkavm/
error.rs

1use alloc::string::{String, ToString};
2use polkavm_common::program::ProgramParseError;
3
4macro_rules! bail {
5    ($($arg:expr),* $(,)?) => {
6        return Err(Error::from_display(format_args!($($arg),*)))
7    }
8}
9
10pub(crate) use bail;
11
12#[derive(Debug)]
13enum ErrorKind {
14    Owned(String),
15    Static(&'static str),
16    ProgramParseError(ProgramParseError),
17}
18
19#[derive(Debug)]
20#[repr(transparent)]
21pub struct Error(ErrorKind);
22
23impl From<&'static str> for Error {
24    #[cold]
25    fn from(message: &'static str) -> Self {
26        Error(ErrorKind::Static(message))
27    }
28}
29
30impl From<String> for Error {
31    #[cold]
32    fn from(string: String) -> Self {
33        Error(ErrorKind::Owned(string))
34    }
35}
36
37impl From<ProgramParseError> for Error {
38    #[cold]
39    fn from(error: ProgramParseError) -> Self {
40        Self(ErrorKind::ProgramParseError(error))
41    }
42}
43
44if_compiler_is_supported! {
45    #[cfg(target_os = "linux")]
46    impl From<polkavm_linux_raw::Error> for Error {
47        #[cold]
48        fn from(error: polkavm_linux_raw::Error) -> Self {
49            Self(ErrorKind::Owned(error.to_string()))
50        }
51    }
52
53    #[cfg(feature = "generic-sandbox")]
54    use crate::sandbox::generic;
55
56    #[cfg(feature = "generic-sandbox")]
57    impl From<generic::Error> for Error {
58        #[cold]
59        fn from(error: generic::Error) -> Self {
60            Self(ErrorKind::Owned(error.to_string()))
61        }
62    }
63}
64
65impl Error {
66    #[cold]
67    pub(crate) fn from_display(message: impl core::fmt::Display) -> Self {
68        Error(ErrorKind::Owned(message.to_string()))
69    }
70
71    #[cold]
72    pub(crate) fn from_static_str(message: &'static str) -> Self {
73        Error(ErrorKind::Static(message))
74    }
75}
76
77if_compiler_is_supported! {
78    impl Error {
79        #[cold]
80        pub(crate) fn context(self, message: impl core::fmt::Display) -> Self {
81            use alloc::format;
82
83            let string = match self.0 {
84                ErrorKind::Owned(buffer) => format!("{}: {}", message, buffer),
85                error => format!("{}: {}", message, Error(error)),
86            };
87
88            Error(ErrorKind::Owned(string))
89        }
90    }
91}
92
93impl core::fmt::Display for Error {
94    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
95        let message = match &self.0 {
96            ErrorKind::Owned(message) => message.as_str(),
97            ErrorKind::Static(message) => message,
98            ErrorKind::ProgramParseError(error) => return error.fmt(fmt),
99        };
100
101        fmt.write_str(message)
102    }
103}
104
105impl core::error::Error for Error {}
106
107impl From<Error> for String {
108    fn from(error: Error) -> String {
109        error.to_string()
110    }
111}