use lazy_static::lazy_static;
use crate::lib::*;
use crate::prelude::Generator;
lazy_static! {
static ref GENERATOR: SequenceGenerator = SequenceGenerator::default();
}
#[derive(Debug)]
struct SequenceGenerator {
value: AtomicUsize,
}
impl Default for SequenceGenerator {
fn default() -> Self {
Self {
value: AtomicUsize::new(0),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct SimpleGenerator<T>
where
T: Into<u128> + Copy,
{
step: T,
}
impl<T> SimpleGenerator<T>
where
T: Into<u128> + Copy,
{
pub fn new(step: T) -> Self {
Self { step }
}
}
impl<T> Generator<T> for SimpleGenerator<T>
where
T: Into<u128> + Copy + Default + From<u128> + Add<Output = T>,
{
fn generate(&self) -> T {
let _ = GENERATOR
.value
.fetch_add(self.step.into() as usize, Ordering::SeqCst);
let val = GENERATOR.value.load(Ordering::SeqCst);
T::from(val as u128)
}
fn with_offset(&self, offset: T) -> T {
let value = self.generate();
value + offset
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple_generator() {
let generator = SimpleGenerator::new(1);
assert_eq!(generator.generate(), 1);
assert_eq!(generator.generate(), 2);
}
}