autoincrement/
sync.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4/// Non-thread-safe container for keeping autoincrement counter
5#[derive(Debug, Clone)]
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7pub struct AutoIncrement<T>(T);
8
9impl<T: Incremental> AutoIncrement<T> {
10    #[allow(clippy::should_implement_trait)]
11    pub fn pull(&mut self) -> T {
12        let next = Incremental::get_next(&self.0);
13        std::mem::replace(&mut self.0, next)
14    }
15
16    pub fn init_with(initial_value: T) -> Self {
17        Self(initial_value)
18    }
19}
20
21impl<T: Clone> AutoIncrement<T> {
22    pub fn current(&self) -> T {
23        self.0.clone()
24    }
25}
26
27/// Trait for implementing over non-thread-safe incremental types
28pub trait Incremental: Sized {
29    fn initial() -> Self;
30
31    fn get_next(current: &Self) -> Self;
32
33    fn init() -> AutoIncrement<Self> {
34        AutoIncrement(Self::initial())
35    }
36
37    fn init_with(value: Self) -> AutoIncrement<Self> {
38        AutoIncrement(value)
39    }
40
41    fn init_from(self) -> AutoIncrement<Self> {
42        Self::init_with(self)
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use crate as autoincrement;
49    #[cfg(feature = "derive")]
50    use autoincrement::Incremental;
51    #[cfg(not(feature = "derive"))]
52    use autoincrement_derive::Incremental;
53
54    #[test]
55    #[cfg(feature = "sync")]
56    fn test_sync_u8() {
57        #[derive(Incremental, Debug, PartialEq, Eq, Clone)]
58        struct MyID(u8);
59
60        let mut counter = MyID::init();
61
62        assert_eq!(counter.current(), MyID(1));
63        assert_eq!(counter.pull(), MyID(1));
64        assert_eq!(counter.current(), MyID(2));
65        assert_eq!(counter.pull(), MyID(2));
66        assert_eq!(counter.current(), MyID(3));
67        assert_eq!(counter.pull(), MyID(3));
68    }
69
70    #[test]
71    #[cfg(feature = "sync")]
72    fn test_sync_u16() {
73        #[derive(Incremental, Debug, PartialEq, Eq, Clone)]
74        struct MyID(u16);
75
76        let mut counter = MyID::init();
77
78        assert_eq!(counter.current(), MyID(1));
79        assert_eq!(counter.pull(), MyID(1));
80        assert_eq!(counter.current(), MyID(2));
81        assert_eq!(counter.pull(), MyID(2));
82        assert_eq!(counter.current(), MyID(3));
83        assert_eq!(counter.pull(), MyID(3));
84    }
85
86    #[test]
87    #[cfg(feature = "sync")]
88    fn test_sync_u32() {
89        #[derive(Incremental, Debug, PartialEq, Eq, Clone)]
90        struct MyID(u32);
91
92        let mut counter = MyID::init();
93
94        assert_eq!(counter.current(), MyID(1));
95        assert_eq!(counter.pull(), MyID(1));
96        assert_eq!(counter.current(), MyID(2));
97        assert_eq!(counter.pull(), MyID(2));
98        assert_eq!(counter.current(), MyID(3));
99        assert_eq!(counter.pull(), MyID(3));
100    }
101
102    #[test]
103    #[cfg(feature = "sync")]
104    fn test_sync_u64() {
105        #[derive(Incremental, Debug, PartialEq, Eq, Clone)]
106        struct MyID(u64);
107
108        let mut counter = MyID::init();
109
110        assert_eq!(counter.current(), MyID(1));
111        assert_eq!(counter.pull(), MyID(1));
112        assert_eq!(counter.current(), MyID(2));
113        assert_eq!(counter.pull(), MyID(2));
114        assert_eq!(counter.current(), MyID(3));
115        assert_eq!(counter.pull(), MyID(3));
116    }
117
118    #[test]
119    #[cfg(feature = "sync")]
120    fn test_sync_usize() {
121        #[derive(Incremental, Debug, PartialEq, Eq, Clone)]
122        struct MyID(usize);
123
124        let mut counter = MyID::init();
125
126        assert_eq!(counter.current(), MyID(1));
127        assert_eq!(counter.pull(), MyID(1));
128        assert_eq!(counter.current(), MyID(2));
129        assert_eq!(counter.pull(), MyID(2));
130        assert_eq!(counter.current(), MyID(3));
131        assert_eq!(counter.pull(), MyID(3));
132    }
133}