use std::time::{SystemTime, UNIX_EPOCH};
use crate::error::SnowflakeError;
use crate::layout::BitLayout;
use crate::utils::get_time_millis;
use crate::generator::SnowflakeIdGenerator;
impl SnowflakeIdGenerator {
pub fn new(machine_id: i64, node_id: i64) -> Result<Self, SnowflakeError> {
Self::with_epoch(machine_id, node_id, UNIX_EPOCH)
}
pub fn with_epoch(
machine_id: i64,
node_id: i64,
epoch: SystemTime,
) -> Result<Self, SnowflakeError> {
Self::with_layout_and_epoch(machine_id, node_id, BitLayout::default(), epoch)
}
pub fn with_layout(
machine_id: i64,
node_id: i64,
layout: BitLayout,
) -> Result<Self, SnowflakeError> {
Self::with_layout_and_epoch(machine_id, node_id, layout, UNIX_EPOCH)
}
pub fn with_layout_and_epoch(
machine_id: i64,
node_id: i64,
layout: BitLayout,
epoch: SystemTime,
) -> Result<Self, SnowflakeError> {
if machine_id < 0 || machine_id > layout.max_machine_id() {
return Err(SnowflakeError::MachineIdOutOfRange {
given: machine_id,
max: layout.max_machine_id(),
});
}
if node_id < 0 || node_id > layout.max_node_id() {
return Err(SnowflakeError::NodeIdOutOfRange {
given: node_id,
max: layout.max_node_id(),
});
}
let last_time_millis = get_time_millis(epoch)?;
Ok(Self {
epoch,
last_time_millis,
machine_id,
node_id,
idx: 0,
layout,
})
}
}