use std::convert::TryFrom;
use std::hash::Hash as StdHash;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use crate::entry::error::LogIdError;
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, StdHash)]
pub struct LogId(u64);
impl LogId {
pub fn new(value: u64) -> Self {
Self(value)
}
pub fn as_u64(&self) -> u64 {
self.0
}
}
impl Default for LogId {
fn default() -> Self {
Self::new(1)
}
}
impl Iterator for LogId {
type Item = LogId;
fn next(&mut self) -> Option<Self::Item> {
Some(Self(self.0 + 1))
}
}
impl FromStr for LogId {
type Err = LogIdError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new(
u64::from_str(s).map_err(|_| LogIdError::InvalidU64String)?,
))
}
}
impl TryFrom<String> for LogId {
type Error = LogIdError;
fn try_from(str: String) -> Result<Self, Self::Error> {
Ok(Self::new(
u64::from_str(&str).map_err(|_| LogIdError::InvalidU64String)?,
))
}
}
#[cfg(test)]
mod tests {
use std::convert::TryFrom;
use super::LogId;
#[test]
fn log_ids() {
let mut log_id = LogId::default();
let mut next_log_id = log_id.next().unwrap();
assert_eq!(next_log_id, LogId::new(2));
let next_log_id = next_log_id.next().unwrap();
assert_eq!(next_log_id, LogId::new(3));
}
#[test]
fn string_conversions() {
let large_number = "291919188205818203";
let log_id_from_str: LogId = large_number.parse().unwrap();
let log_id_try_from = LogId::try_from(String::from(large_number)).unwrap();
assert_eq!(291919188205818203, log_id_from_str.as_u64());
assert_eq!(log_id_from_str, log_id_try_from);
}
}