use tokio::sync::Mutex;
use topcoat_core::{
context::{Cx, request_context},
error::Result,
};
use crate::{Token, token_store};
#[derive(Debug, Default)]
pub struct SessionState {
token: Mutex<Load>,
}
#[derive(Debug, Default)]
enum Load {
#[default]
Unloaded,
Loaded(Option<Token>),
}
impl SessionState {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub(crate) async fn token(&self, cx: &Cx) -> Result<Option<Token>> {
let mut load = self.token.lock().await;
if let Load::Loaded(token) = &*load {
return Ok(token.clone());
}
let token = token_store(cx).read(cx).await?;
*load = Load::Loaded(token.clone());
Ok(token)
}
pub(crate) async fn set(&self, token: Option<Token>) {
*self.token.lock().await = Load::Loaded(token);
}
}
pub(crate) fn state(cx: &Cx) -> &SessionState {
request_context(cx)
}