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}