Skip to main content

surreal_client/
session.rs

1use serde_json::Value;
2use std::collections::HashMap;
3
4/// Session state management for SurrealDB connections
5#[derive(Debug, Clone, Default)]
6pub struct SessionState {
7    /// Current namespace
8    pub namespace: Option<String>,
9
10    /// Current database
11    pub database: Option<String>,
12
13    /// Authentication token
14    pub token: Option<String>,
15
16    /// Current scope (for record-level authentication)
17    pub scope: Option<String>,
18
19    /// Session parameters set via `let`
20    pub params: HashMap<String, Value>,
21}
22
23impl SessionState {
24    /// Create a new empty session state
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    /// Set the namespace
30    pub fn set_namespace(&mut self, namespace: Option<String>) {
31        self.namespace = namespace;
32    }
33
34    /// Set the database
35    pub fn set_database(&mut self, database: Option<String>) {
36        self.database = database;
37    }
38
39    /// Set the authentication token
40    pub fn set_token(&mut self, token: Option<String>) {
41        self.token = token;
42    }
43
44    /// Set the scope
45    pub fn set_scope(&mut self, scope: Option<String>) {
46        self.scope = scope;
47    }
48
49    /// Set a session parameter
50    pub fn set_param(&mut self, key: String, value: Value) {
51        self.params.insert(key, value);
52    }
53
54    /// Remove a session parameter
55    pub fn unset_param(&mut self, key: &str) {
56        self.params.remove(key);
57    }
58
59    /// Get a session parameter
60    pub fn get_param(&self, key: &str) -> Option<&Value> {
61        self.params.get(key)
62    }
63
64    /// Clear all session parameters
65    pub fn clear_params(&mut self) {
66        self.params.clear();
67    }
68
69    /// Check if authenticated (has a token)
70    pub fn is_authenticated(&self) -> bool {
71        self.token.is_some()
72    }
73
74    /// Get the current namespace/database pair as a tuple
75    pub fn get_target(&self) -> (Option<&String>, Option<&String>) {
76        (self.namespace.as_ref(), self.database.as_ref())
77    }
78
79    /// Set both namespace and database at once
80    pub fn set_target(&mut self, namespace: Option<String>, database: Option<String>) {
81        self.namespace = namespace;
82        self.database = database;
83    }
84
85    /// Clear all authentication data
86    pub fn clear_auth(&mut self) {
87        self.token = None;
88        self.scope = None;
89    }
90
91    /// Reset the entire session state
92    pub fn reset(&mut self) {
93        self.namespace = None;
94        self.database = None;
95        self.token = None;
96        self.scope = None;
97        self.params.clear();
98    }
99
100    /// Get all parameters as a reference
101    pub fn params(&self) -> &HashMap<String, Value> {
102        &self.params
103    }
104
105    /// Merge parameters from another map
106    pub fn merge_params(&mut self, params: HashMap<String, Value>) {
107        for (key, value) in params {
108            self.params.insert(key, value);
109        }
110    }
111}
112
113#[cfg(test)]
114mod tests {
115    use super::*;
116    use serde_json::json;
117
118    #[test]
119    fn test_session_state_creation() {
120        let session = SessionState::new();
121        assert!(session.namespace.is_none());
122        assert!(session.database.is_none());
123        assert!(session.token.is_none());
124        assert!(session.params.is_empty());
125    }
126
127    #[test]
128    fn test_session_state_setters() {
129        let mut session = SessionState::new();
130
131        session.set_namespace(Some("test_ns".to_string()));
132        session.set_database(Some("test_db".to_string()));
133        session.set_token(Some("jwt_token".to_string()));
134
135        assert_eq!(session.namespace, Some("test_ns".to_string()));
136        assert_eq!(session.database, Some("test_db".to_string()));
137        assert_eq!(session.token, Some("jwt_token".to_string()));
138        assert!(session.is_authenticated());
139    }
140
141    #[test]
142    fn test_session_parameters() {
143        let mut session = SessionState::new();
144
145        session.set_param("user_id".to_string(), json!(123));
146        session.set_param("role".to_string(), json!("admin"));
147
148        assert_eq!(session.get_param("user_id"), Some(&json!(123)));
149        assert_eq!(session.get_param("role"), Some(&json!("admin")));
150        assert_eq!(session.params.len(), 2);
151
152        session.unset_param("user_id");
153        assert!(session.get_param("user_id").is_none());
154        assert_eq!(session.params.len(), 1);
155
156        session.clear_params();
157        assert!(session.params.is_empty());
158    }
159
160    #[test]
161    fn test_session_target() {
162        let mut session = SessionState::new();
163
164        session.set_target(Some("ns".to_string()), Some("db".to_string()));
165        let (ns, db) = session.get_target();
166
167        assert_eq!(ns, Some(&"ns".to_string()));
168        assert_eq!(db, Some(&"db".to_string()));
169    }
170
171    #[test]
172    fn test_session_reset() {
173        let mut session = SessionState::new();
174
175        session.set_namespace(Some("test".to_string()));
176        session.set_token(Some("token".to_string()));
177        session.set_param("key".to_string(), json!("value"));
178
179        session.reset();
180
181        assert!(session.namespace.is_none());
182        assert!(session.token.is_none());
183        assert!(session.params.is_empty());
184        assert!(!session.is_authenticated());
185    }
186
187    #[test]
188    fn test_merge_params() {
189        let mut session = SessionState::new();
190        session.set_param("existing".to_string(), json!("old"));
191
192        let mut new_params = HashMap::new();
193        new_params.insert("new".to_string(), json!("value"));
194        new_params.insert("existing".to_string(), json!("updated"));
195
196        session.merge_params(new_params);
197
198        assert_eq!(session.get_param("new"), Some(&json!("value")));
199        assert_eq!(session.get_param("existing"), Some(&json!("updated")));
200    }
201}