algocline_core/execution/
session_id.rs1use std::sync::atomic::{AtomicU64, Ordering};
4use std::time::{SystemTime, UNIX_EPOCH};
5
6use serde::{Deserialize, Serialize};
7
8static SESSION_COUNTER: AtomicU64 = AtomicU64::new(0);
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
21#[serde(transparent)]
22pub struct SessionId(String);
23
24impl SessionId {
25 pub fn new(s: String) -> Self {
27 Self(s)
28 }
29
30 pub fn generate() -> Self {
36 let ms = SystemTime::now()
37 .duration_since(UNIX_EPOCH)
38 .unwrap_or_default()
39 .as_millis() as u64;
40 let counter = SESSION_COUNTER.fetch_add(1, Ordering::Relaxed);
41 Self(format!("ses-{ms}-{counter}"))
42 }
43
44 pub fn as_str(&self) -> &str {
46 &self.0
47 }
48}
49
50impl std::fmt::Display for SessionId {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 f.write_str(&self.0)
53 }
54}
55
56impl From<String> for SessionId {
57 fn from(s: String) -> Self {
58 Self(s)
59 }
60}
61
62impl From<&str> for SessionId {
63 fn from(s: &str) -> Self {
64 Self(s.to_owned())
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn session_id_serde_string_form() {
74 let id = SessionId::new("01HX1234567890ABCDEFGHJKMP".to_owned());
76 let json = serde_json::to_string(&id).expect("serialize");
77 assert_eq!(json, r#""01HX1234567890ABCDEFGHJKMP""#);
78
79 let roundtripped: SessionId = serde_json::from_str(&json).expect("deserialize");
80 assert_eq!(roundtripped, id);
81 }
82
83 #[test]
84 fn session_id_display() {
85 let id = SessionId::new("abc123".to_owned());
86 assert_eq!(id.to_string(), "abc123");
87 }
88}