use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ContextData {
pub user_id: Option<String>,
pub tenant_id: Option<String>,
pub request_id: Option<String>,
pub extras: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct Context {
data: Arc<RwLock<ContextData>>,
}
impl Context {
pub fn new() -> Self {
Self {
data: Arc::new(RwLock::new(ContextData::default())),
}
}
pub async fn set_user_id(&self, user_id: impl Into<String>) {
let mut data = self.data.write().await;
data.user_id = Some(user_id.into());
}
pub async fn user_id(&self) -> Option<String> {
let data = self.data.read().await;
data.user_id.clone()
}
pub async fn set_tenant_id(&self, tenant_id: impl Into<String>) {
let mut data = self.data.write().await;
data.tenant_id = Some(tenant_id.into());
}
pub async fn tenant_id(&self) -> Option<String> {
let data = self.data.read().await;
data.tenant_id.clone()
}
pub async fn set_request_id(&self, request_id: impl Into<String>) {
let mut data = self.data.write().await;
data.request_id = Some(request_id.into());
}
pub async fn request_id(&self) -> Option<String> {
let data = self.data.read().await;
data.request_id.clone()
}
pub async fn set_extra(&self, key: impl Into<String>, value: impl Into<String>) {
let mut data = self.data.write().await;
data.extras.insert(key.into(), value.into());
}
pub async fn extra(&self, key: &str) -> Option<String> {
let data = self.data.read().await;
data.extras.get(key).cloned()
}
}
impl Default for Context {
fn default() -> Self {
Self::new()
}
}