Skip to main content

ccs_proxy/
session.rs

1use chrono::Utc;
2use std::fmt;
3use std::str::FromStr;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct SessionId(pub(crate) String);
7
8impl SessionId {
9    pub fn new() -> Self {
10        let ts = Utc::now().format("%Y-%m-%dT%H-%M-%S-%3fZ").to_string();
11        let suffix: String = uuid::Uuid::new_v4()
12            .to_string()
13            .chars()
14            .filter(|c| c.is_ascii_alphanumeric())
15            .take(8)
16            .collect();
17        Self(format!("{ts}-{suffix}"))
18    }
19
20    pub fn as_str(&self) -> &str {
21        &self.0
22    }
23}
24
25impl Default for SessionId {
26    fn default() -> Self {
27        Self::new()
28    }
29}
30
31impl fmt::Display for SessionId {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        f.write_str(&self.0)
34    }
35}
36
37#[derive(Debug, thiserror::Error)]
38#[error("invalid session id: {0}")]
39pub struct InvalidSessionId(pub String);
40
41impl FromStr for SessionId {
42    type Err = InvalidSessionId;
43    fn from_str(s: &str) -> Result<Self, Self::Err> {
44        if s.is_empty()
45            || s.len() > 64
46            || !s
47                .chars()
48                .all(|c| c.is_ascii_alphanumeric() || c == '-' || c == 'T' || c == 'Z')
49        {
50            return Err(InvalidSessionId(s.to_string()));
51        }
52        Ok(Self(s.to_string()))
53    }
54}