coven_core/
id_provider.rs1use std::sync::Arc;
12use uuid::Uuid;
13
14pub trait IdProvider: Send + Sync {
16 fn new_id(&self) -> String;
18}
19
20pub type IdRef = Arc<dyn IdProvider>;
23
24pub struct UuidProvider;
26
27impl IdProvider for UuidProvider {
28 fn new_id(&self) -> String {
29 Uuid::new_v4().to_string()
30 }
31}
32
33#[cfg(any(test, feature = "test-utils"))]
37pub use fakes::SequentialIdProvider;
38
39#[cfg(any(test, feature = "test-utils"))]
40mod fakes {
41 use super::*;
42 use std::sync::atomic::{AtomicU64, Ordering};
43
44 pub struct SequentialIdProvider {
47 prefix: String,
48 next: AtomicU64,
49 }
50
51 impl SequentialIdProvider {
52 pub fn new(prefix: &str) -> Self {
53 Self {
54 prefix: prefix.to_string(),
55 next: AtomicU64::new(0),
56 }
57 }
58 }
59
60 impl IdProvider for SequentialIdProvider {
61 fn new_id(&self) -> String {
62 let n = self.next.fetch_add(1, Ordering::SeqCst);
63 format!("{}-{}", self.prefix, n)
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn sequential_ids_are_deterministic_and_unique() {
74 let ids = SequentialIdProvider::new("id");
75 assert_eq!(ids.new_id(), "id-0");
76 assert_eq!(ids.new_id(), "id-1");
77 assert_eq!(ids.new_id(), "id-2");
78 }
79
80 #[test]
81 fn provider_is_usable_behind_the_shared_handle() {
82 let ids: IdRef = Arc::new(SequentialIdProvider::new("row"));
83 assert_eq!(ids.new_id(), "row-0");
84 assert_ne!(ids.new_id(), ids.new_id());
85 }
86}