Skip to main content

ecr_server/
state.rs

1use crate::auth::TokenStore;
2use crate::events::EventBus;
3use ecr_core::revision::Revision;
4use ecr_store::NotmuchStore;
5use std::sync::Arc;
6use tokio::sync::RwLock;
7
8#[derive(Clone)]
9pub struct AppState {
10    pub store: Arc<NotmuchStore>,
11    pub tokens: Arc<RwLock<TokenStore>>,
12    pub events: EventBus,
13    pub read_only: bool,
14    /// The revision this server's own last tag write left behind. See
15    /// `own_write`.
16    written: Arc<RwLock<Option<Revision>>>,
17}
18
19impl AppState {
20    pub fn new(store: Arc<NotmuchStore>, tokens: TokenStore, read_only: bool) -> Self {
21        Self {
22            store,
23            tokens: Arc::new(RwLock::new(tokens)),
24            events: EventBus::new(),
25            read_only,
26            written: Arc::new(RwLock::new(None)),
27        }
28    }
29
30    pub async fn requires_auth(&self) -> bool {
31        !self.tokens.read().await.is_empty()
32    }
33
34    /// Remembers what a tag write left the database at. notmuch synchronises
35    /// maildir flags, so dropping `unread` renames the file — which the
36    /// delivery watcher sees, and would otherwise announce as new mail.
37    pub async fn note_own_write(&self, revision: &Revision) {
38        *self.written.write().await = Some(revision.clone());
39    }
40
41    /// Whether the database still stands exactly where this server's own last
42    /// write left it, meaning nothing has been delivered since.
43    pub async fn own_write(&self, observed: &Revision) -> bool {
44        self.written.read().await.as_ref() == Some(observed)
45    }
46}