distri-types 0.3.8

Shared message, tool, and config types for Distri
Documentation
use std::future::Future;
use uuid::Uuid;

tokio::task_local! {
    static CURRENT_USER_ID: String;
    static CURRENT_WORKSPACE_ID: Uuid;
}

#[derive(Clone)]
pub struct UserContext {
    user_id: String,
    workspace_id: Option<String>,
}

impl UserContext {
    pub fn new(user_id: String) -> Self {
        Self {
            user_id,
            workspace_id: None,
        }
    }

    pub fn with_workspace(user_id: String, workspace_id: Option<String>) -> Self {
        Self {
            user_id,
            workspace_id,
        }
    }

    pub fn user_id(&self) -> String {
        self.user_id.clone()
    }

    pub fn workspace_id(&self) -> Option<String> {
        self.workspace_id.clone()
    }
}

pub fn current_user_id() -> Option<String> {
    CURRENT_USER_ID.try_with(|id| id.clone()).ok()
}

pub fn current_workspace_id() -> Option<Uuid> {
    CURRENT_WORKSPACE_ID.try_with(|id| *id).ok()
}

pub async fn with_user_id<F, T>(user_id: String, fut: F) -> T
where
    F: Future<Output = T>,
{
    CURRENT_USER_ID.scope(user_id, fut).await
}

pub async fn with_user_and_workspace<F, T>(user_id: String, workspace_id: Option<Uuid>, fut: F) -> T
where
    F: Future<Output = T>,
{
    match workspace_id {
        Some(ws_id) => {
            CURRENT_USER_ID
                .scope(user_id, CURRENT_WORKSPACE_ID.scope(ws_id, fut))
                .await
        }
        None => CURRENT_USER_ID.scope(user_id, fut).await,
    }
}