indy_utils/
macros.rs

1macro_rules! unwrap_opt_or_return {
2    ($opt:expr, $err:expr) => {
3        match $opt {
4            Some(val) => val,
5            None => return $err,
6        }
7    };
8}
9
10/// Used to optionally add Serialize and Deserialize traits to Qualifiable types
11#[cfg(feature = "serde")]
12#[macro_export]
13macro_rules! serde_derive_impl {
14    ($def:item) => {
15        #[derive(Serialize, Deserialize)]
16        $def
17    };
18}
19
20#[cfg(not(feature = "serde"))]
21#[macro_export]
22macro_rules! serde_derive_impl {
23    ($def:item) => {
24        $def
25    };
26}
27
28/// Derive a new handle type having an atomically increasing sequence number
29#[macro_export]
30macro_rules! new_handle_type (($newtype:ident, $counter:ident) => (
31    static $counter: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
32
33    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
34    #[repr(transparent)]
35    pub struct $newtype(pub usize);
36
37    impl $newtype {
38        #[allow(dead_code)]
39        pub fn invalid() -> $newtype {
40            $newtype(0)
41        }
42
43        #[allow(dead_code)]
44        pub fn next() -> $newtype {
45            $newtype($counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1)
46        }
47    }
48
49    impl std::fmt::Display for $newtype {
50        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51            write!(f, "{}({})", stringify!($newtype), self.0)
52        }
53    }
54
55    impl std::ops::Deref for $newtype {
56        type Target = usize;
57        fn deref(&self) -> &usize {
58            &self.0
59        }
60    }
61
62    impl PartialEq<usize> for $newtype {
63        fn eq(&self, other: &usize) -> bool {
64            self.0 == *other
65        }
66    }
67
68    impl $crate::Validatable for $newtype {
69        fn validate(&self) -> std::result::Result<(), $crate::ValidationError> {
70            if(**self == 0) {
71                Err("Invalid handle: zero".into())
72            } else {
73                Ok(())
74            }
75        }
76    }
77));
78
79#[cfg(test)]
80mod tests {
81    new_handle_type!(TestHandle, TEST_HANDLE_CTR);
82
83    #[test]
84    fn test_handle_seq() {
85        assert_eq!(TestHandle::next(), 1);
86        assert_eq!(TestHandle::next(), 2);
87    }
88}