Skip to main content

safer_ffi_gen/
error.rs

1#[cfg(feature = "std")]
2mod with_std;
3
4#[cfg(not(feature = "std"))]
5mod without_std;
6
7#[cfg(feature = "std")]
8pub use with_std::{last_error, set_last_error, WrapDebug, WrapError, WrapNotDebug, WrapNotError};
9
10#[macro_export]
11macro_rules! error_code {
12    ($e:expr) => {{
13        #[allow(unused_imports)]
14        use $crate::private::{WrapIntoInt, WrapNotIntoInt};
15
16        let e = &$e;
17        e.safer_ffi_gen_wrap_into_int()
18    }};
19}
20
21pub trait WrapIntoInt {
22    fn safer_ffi_gen_wrap_into_int(&self) -> i32;
23}
24
25impl<T> WrapIntoInt for T
26where
27    for<'a> &'a T: Into<i32>,
28{
29    fn safer_ffi_gen_wrap_into_int(&self) -> i32 {
30        self.into()
31    }
32}
33
34pub trait WrapNotIntoInt {
35    fn safer_ffi_gen_wrap_into_int(&self) -> i32 {
36        -1
37    }
38}
39
40impl<T> WrapNotIntoInt for &T {}
41
42#[cfg(test)]
43mod tests {
44    #[test]
45    fn error_code_uses_int_conversion_when_it_exists() {
46        struct Foo;
47
48        impl From<&Foo> for i32 {
49            fn from(_: &Foo) -> Self {
50                33
51            }
52        }
53
54        assert_eq!(crate::error_code!(Foo), 33);
55    }
56
57    #[test]
58    fn error_code_returns_negative_when_int_conversion_does_not_exist() {
59        struct Foo;
60
61        assert_eq!(crate::error_code!(Foo), -1);
62    }
63}