simple_counter/
lib.rs

1/// Generates a thread-local global counter.
2///
3/// # Example
4///
5/// ```rust
6/// #[macro_use]
7/// extern crate simple_counter;
8/// 
9/// generate_counter!(Counter, usize);
10/// 
11/// fn main() {
12/// 
13///   assert_eq!(Counter::next(), 0);
14///   assert_eq!(Counter::next(), 1);
15///   assert_eq!(Counter::next(), 2);
16/// 
17///   Counter::reset();
18/// 
19///   assert_eq!(Counter::next(), 0);
20/// }
21/// ```
22#[macro_export]
23macro_rules! generate_counter {
24    ($name:ident, $type:ident) => {
25
26        /// Generated by the `simple-counter` crate.
27        #[allow(non_snake_case)]
28        pub mod $name {
29            use std::cell::Cell;
30
31            thread_local!(
32                static COUNTER: Cell<$type> = Cell::new(0);
33            );
34
35            pub fn next() -> $type {
36                COUNTER.with(|cell| {
37                    let n = cell.get();
38                    cell.set(n + 1);
39                    n
40                })
41            }
42
43            #[allow(dead_code)]
44            pub fn set(n: $type) {
45                COUNTER.with(|cell| cell.set(n));
46            }
47
48            #[allow(dead_code)]
49            pub fn reset() {
50                COUNTER.with(|cell| cell.set(0));
51            }
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58
59    #[test]
60    fn test_basic() {
61        generate_counter!(Counter, i8);
62        assert_eq!(0, Counter::next());
63        assert_eq!(1, Counter::next());
64        assert_eq!(2, Counter::next());
65    }
66
67    #[test]
68    fn test_reset() {
69        generate_counter!(Counter, i8);
70        assert_eq!(0, Counter::next());
71        assert_eq!(1, Counter::next());
72        Counter::reset();
73        assert_eq!(0, Counter::next());
74    }
75
76    #[test]
77    fn test_set() {
78        generate_counter!(Counter, u32);
79        Counter::set(100);
80        assert_eq!(100, Counter::next());
81        assert_eq!(101, Counter::next());
82        assert_eq!(102, Counter::next());
83    }
84}