mod nanoid;
mod snowflake;
mod ulid;
use std::error::Error;
use std::future::Future;
use std::pin::Pin;
pub use nanoid::{NanoId, NanoIdConfig, NanoIdError};
pub use snowflake::{Snowflake, SnowflakeConfig, SnowflakeError};
pub use ulid::{Ulid, UlidConfig, UlidError};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum IdType {
#[default]
Numeric64,
String128,
ShortString,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Id {
Numeric64(u64),
String(String),
}
impl Id {
pub fn as_string(&self) -> String {
match self {
Id::Numeric64(n) => n.to_string(),
Id::String(s) => s.clone(),
}
}
pub fn as_u64(&self) -> Option<u64> {
match self {
Id::Numeric64(n) => Some(*n),
Id::String(_) => None,
}
}
}
impl std::fmt::Display for Id {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Id::Numeric64(n) => write!(f, "{}", n),
Id::String(s) => write!(f, "{}", s),
}
}
}
impl From<u64> for Id {
fn from(n: u64) -> Self {
Id::Numeric64(n)
}
}
impl From<String> for Id {
fn from(s: String) -> Self {
Id::String(s)
}
}
impl From<&str> for Id {
fn from(s: &str) -> Self {
Id::String(s.to_string())
}
}
pub trait IdGenerator: Send + Sync {
type Error: Error + Send + Sync + 'static;
fn generate(&self) -> Pin<Box<dyn Future<Output = Result<Id, Self::Error>> + Send + '_>>;
#[allow(clippy::type_complexity)]
fn generate_batch(
&self,
count: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Id>, Self::Error>> + Send + '_>> {
Box::pin(async move {
let mut ids = Vec::with_capacity(count);
for _ in 0..count {
ids.push(self.generate().await?);
}
Ok(ids)
})
}
fn id_type(&self) -> IdType;
}