1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4#[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
27pub 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}