1use tokio::sync::Mutex;
2use topcoat_core::{
3 context::{Cx, request_context},
4 error::Result,
5};
6
7use crate::{Token, token_store};
8
9#[derive(Debug, Default)]
18pub struct SessionState {
19 token: Mutex<Load>,
20}
21
22#[derive(Debug, Default)]
23enum Load {
24 #[default]
25 Unloaded,
26 Loaded(Option<Token>),
27}
28
29impl SessionState {
30 #[must_use]
32 pub fn new() -> Self {
33 Self::default()
34 }
35
36 pub(crate) async fn token(&self, cx: &Cx) -> Result<Option<Token>> {
39 let mut load = self.token.lock().await;
40 if let Load::Loaded(token) = &*load {
41 return Ok(token.clone());
42 }
43 let token = token_store(cx).read(cx).await?;
44 *load = Load::Loaded(token.clone());
45 Ok(token)
46 }
47
48 pub(crate) async fn set(&self, token: Option<Token>) {
50 *self.token.lock().await = Load::Loaded(token);
51 }
52}
53
54pub(crate) fn state(cx: &Cx) -> &SessionState {
55 request_context(cx)
56}