use std::collections::HashSet;
use std::thread;
use typedflake::{GenerateError, GeneratorError, InitError, NodeError, TypedNode, typedflake};
#[derive(Debug, Clone, Copy, TypedNode)]
pub struct AppNode {
#[node(bits = 5)]
pub worker: u8,
#[node(bits = 5)]
pub process: u8,
}
#[typedflake(epoch = "2025-01-01")]
pub struct UserId(i64);
#[typedflake(epoch = "2025-01-01")]
pub struct OrderId(u64);
#[typedflake(epoch = "2025-01-01", bits(timestamp = 41, node = 3, sequence = 12))]
pub struct NarrowId(i64);
#[typedflake(epoch = "2025-01-01", node = AppNode)]
pub struct TypedId(i64);
#[test]
fn plain_node_default_lifecycle() {
assert!(matches!(
UserId::generate(),
Err(GenerateError::NotInitialized { node: "u32" })
));
assert!(matches!(
UserId::generate_blocking(),
Err(GenerateError::NotInitialized { node: "u32" })
));
assert_eq!(UserId::try_from(42_i64).unwrap().get(), 42);
assert_eq!(
UserId::generator(3)
.unwrap()
.generate()
.unwrap()
.parts()
.node,
3
);
assert_eq!(typedflake::init(17), Ok(()));
assert_eq!(typedflake::init(17), Err(InitError::AlreadyInitialized));
assert_eq!(typedflake::init(18), Err(InitError::AlreadyInitialized));
assert_eq!(UserId::generate().unwrap().parts().node, 17);
assert_eq!(OrderId::generate().unwrap().parts().node, 17);
assert_eq!(UserId::generate_blocking().unwrap().parts().node, 17);
assert!(matches!(
NarrowId::generate(),
Err(GenerateError::DefaultGenerator(GeneratorError::InvalidNode(error)))
if error == NodeError::new("node", 17, 7)
));
match TypedId::generate() {
Err(error @ GenerateError::NotInitialized { node }) => {
assert!(node.ends_with("AppNode"), "{node}");
assert!(error.to_string().contains("AppNode"), "{error}");
}
other => panic!("expected a missing default, got {other:?}"),
}
let typed = AppNode {
worker: 1,
process: 1,
};
assert!(TypedId::generator(typed).unwrap().generate().is_ok());
let ids: Vec<UserId> = thread::scope(|scope| {
let statics = scope.spawn(|| {
(0..20_000)
.map(|_| UserId::generate_blocking().unwrap())
.collect::<Vec<_>>()
});
let explicit = scope.spawn(|| {
let generator = UserId::generator(17).unwrap();
(0..20_000)
.map(|_| generator.generate_blocking().unwrap())
.collect::<Vec<_>>()
});
let mut ids = statics.join().unwrap();
ids.extend(explicit.join().unwrap());
ids
});
let unique: HashSet<UserId> = ids.iter().copied().collect();
assert_eq!(unique.len(), ids.len());
}