elfo_core/dumping/
sequence_no.rs

1use std::{
2    convert::TryFrom,
3    num::{NonZeroU64, TryFromIntError},
4    sync::atomic::{AtomicU64, Ordering},
5};
6
7use serde::Serialize;
8
9// TODO: make it just type alias (or not?)
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
11pub struct SequenceNo(NonZeroU64);
12
13impl TryFrom<u64> for SequenceNo {
14    type Error = TryFromIntError;
15
16    #[inline]
17    fn try_from(raw: u64) -> Result<Self, Self::Error> {
18        NonZeroU64::try_from(raw).map(Self)
19    }
20}
21
22impl From<SequenceNo> for u64 {
23    #[inline]
24    fn from(sequence_no: SequenceNo) -> Self {
25        sequence_no.0.get()
26    }
27}
28
29pub(crate) struct SequenceNoGenerator {
30    next_sequence_no: AtomicU64,
31}
32
33impl Default for SequenceNoGenerator {
34    fn default() -> Self {
35        Self {
36            // We starts with `1` here because `SequenceNo` is supposed to be non-zero.
37            next_sequence_no: AtomicU64::new(1),
38        }
39    }
40}
41
42impl SequenceNoGenerator {
43    pub(crate) fn generate(&self) -> SequenceNo {
44        let raw = self.next_sequence_no.fetch_add(1, Ordering::Relaxed);
45        NonZeroU64::new(raw).map(SequenceNo).expect("impossible")
46    }
47}