rust_mcp_sdk/id_generator/fast_id_generator.rs
1use crate::mcp_traits::IdGenerator;
2use base64::Engine;
3use std::sync::atomic::{AtomicU64, Ordering};
4
5/// An [`IdGenerator`] implementation optimized for lightweight, locally-scoped identifiers.
6///
7/// This generator produces short, incrementing identifiers that are Base64-encoded.
8/// This makes it well-suited for cases such as `StreamId` generation, where:
9/// - IDs only need to be unique within a single process or session
10/// - Predictability is acceptable
11/// - Shorter, more human-readable identifiers are desirable
12///
13pub struct FastIdGenerator {
14 counter: AtomicU64,
15 ///Optional prefix for readability
16 prefix: &'static str,
17}
18
19impl FastIdGenerator {
20 /// Creates a new ID generator with an optional prefix.
21 ///
22 /// # Arguments
23 /// * `prefix` - A static string to prepend to IDs (e.g., "sid_").
24 pub fn new(prefix: Option<&'static str>) -> Self {
25 FastIdGenerator {
26 counter: AtomicU64::new(0),
27 prefix: prefix.unwrap_or_default(),
28 }
29 }
30}
31
32impl<T> IdGenerator<T> for FastIdGenerator
33where
34 T: From<String>,
35{
36 /// Generates a new session ID as a short Base64-encoded string.
37 ///
38 /// Increments an internal counter atomically and encodes it in Base64 URL-safe format.
39 /// The resulting ID is prefixed (if provided) and typically 8–12 characters long.
40 ///
41 /// # Returns
42 /// * `SessionId` - A short, unique session ID (e.g., "sid_BBBB" or "BBBB").
43 fn generate(&self) -> T {
44 let id = self.counter.fetch_add(1, Ordering::Relaxed);
45 let bytes = id.to_le_bytes();
46 let encoded = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes);
47 if self.prefix.is_empty() {
48 T::from(encoded)
49 } else {
50 T::from(format!("{}{}", self.prefix, encoded))
51 }
52 }
53}