use crate::Serial;
use std::{
fmt,
fmt::{Display, Formatter},
mem::replace,
};
#[cfg(feature = "serde_impl")]
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde_impl", derive(Deserialize, Serialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct SerialGenerator<T: Serial = u32> {
value: T,
}
impl<T: Serial> SerialGenerator<T> {
pub fn new() -> Self {
Self::default()
}
pub fn with_init_value(value: T) -> Self {
SerialGenerator { value }
}
pub fn generate(&mut self) -> T {
let next = self.value.next_increment();
replace(&mut self.value, next)
}
pub fn previous(&self) -> Option<T> {
if self.value == T::START {
None
} else {
Some(self.value.prev_increment())
}
}
pub fn is_at_max(&self) -> bool {
self.value.is_max_value()
}
}
impl<T: Serial, U: Serial + From<T>> From<T> for SerialGenerator<U> {
fn from(other: T) -> Self {
SerialGenerator::with_init_value(other.into())
}
}
impl<T: Serial> Default for SerialGenerator<T> {
fn default() -> Self {
SerialGenerator { value: T::START }
}
}
impl<T: fmt::Debug + Display + Serial> Display for SerialGenerator<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl<T: Serial> Iterator for SerialGenerator<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.is_at_max() {
None
} else {
let next_value = self.generate();
Some(next_value)
}
}
}