Skip to main content

rusmes_imap/
session.rs

1//! IMAP session state machine
2
3use rusmes_proto::Username;
4use rusmes_storage::MailboxId;
5use std::time::Duration;
6
7/// IMAP session state
8#[derive(Debug, Clone, PartialEq)]
9pub enum ImapState {
10    /// Not authenticated
11    NotAuthenticated,
12    /// Authenticated but no mailbox selected
13    Authenticated,
14    /// Mailbox selected
15    Selected { mailbox_id: MailboxId },
16    /// In IDLE mode (RFC 2177)
17    Idle { mailbox_id: MailboxId },
18    /// Logout
19    Logout,
20}
21
22/// Mailbox snapshot for change detection during IDLE
23#[derive(Debug, Clone)]
24pub struct MailboxSnapshot {
25    pub exists: u32,
26    pub recent: u32,
27}
28
29/// IMAP session
30pub struct ImapSession {
31    pub state: ImapState,
32    pub tag: Option<String>,
33    pub username: Option<Username>,
34    pub mailbox_snapshot: Option<MailboxSnapshot>,
35    pub idle_timeout: Duration,
36}
37
38impl ImapSession {
39    /// Create a new IMAP session with default timeout
40    pub fn new() -> Self {
41        Self::new_with_timeout(Duration::from_secs(1800))
42    }
43
44    /// Create a new IMAP session with custom timeout
45    pub fn new_with_timeout(idle_timeout: Duration) -> Self {
46        Self {
47            state: ImapState::NotAuthenticated,
48            tag: None,
49            username: None,
50            mailbox_snapshot: None,
51            idle_timeout,
52        }
53    }
54
55    /// Get current state
56    pub fn state(&self) -> &ImapState {
57        &self.state
58    }
59
60    /// Update mailbox snapshot
61    pub fn update_snapshot(&mut self, exists: u32, recent: u32) {
62        self.mailbox_snapshot = Some(MailboxSnapshot { exists, recent });
63    }
64
65    /// Get mailbox ID from current state
66    pub fn mailbox_id(&self) -> Option<&MailboxId> {
67        match &self.state {
68            ImapState::Selected { mailbox_id } | ImapState::Idle { mailbox_id } => Some(mailbox_id),
69            _ => None,
70        }
71    }
72}
73
74impl Default for ImapSession {
75    fn default() -> Self {
76        Self::new()
77    }
78}