Skip to main content

rusmes_storage/
traits.rs

1//! Storage abstraction traits
2
3use crate::types::{
4    Mailbox, MailboxCounters, MailboxId, MailboxPath, MessageFlags, MessageMetadata, Quota,
5    SearchCriteria, SpecialUseAttributes,
6};
7use async_trait::async_trait;
8use rusmes_proto::{Mail, MessageId, Username};
9use std::sync::Arc;
10
11/// Mailbox storage operations
12#[async_trait]
13pub trait MailboxStore: Send + Sync {
14    /// Create a new mailbox
15    async fn create_mailbox(&self, path: &MailboxPath) -> anyhow::Result<MailboxId>;
16
17    /// Create a new mailbox with special-use attributes
18    async fn create_mailbox_with_special_use(
19        &self,
20        path: &MailboxPath,
21        special_use: SpecialUseAttributes,
22    ) -> anyhow::Result<MailboxId> {
23        // Default implementation creates mailbox and sets attributes separately
24        let id = self.create_mailbox(path).await?;
25        self.set_mailbox_special_use(&id, special_use).await?;
26        Ok(id)
27    }
28
29    /// Delete a mailbox
30    async fn delete_mailbox(&self, id: &MailboxId) -> anyhow::Result<()>;
31
32    /// Rename a mailbox
33    async fn rename_mailbox(&self, id: &MailboxId, new_path: &MailboxPath) -> anyhow::Result<()>;
34
35    /// Get mailbox by ID
36    async fn get_mailbox(&self, id: &MailboxId) -> anyhow::Result<Option<Mailbox>>;
37
38    /// List all mailboxes for a user
39    async fn list_mailboxes(&self, user: &Username) -> anyhow::Result<Vec<Mailbox>>;
40
41    /// Get a user's INBOX mailbox ID (primary mailbox)
42    async fn get_user_inbox(&self, user: &Username) -> anyhow::Result<Option<MailboxId>>;
43
44    /// Get mailbox special-use attributes
45    async fn get_mailbox_special_use(
46        &self,
47        _id: &MailboxId,
48    ) -> anyhow::Result<SpecialUseAttributes> {
49        // Default implementation returns empty attributes
50        Ok(SpecialUseAttributes::new())
51    }
52
53    /// Set mailbox special-use attributes
54    async fn set_mailbox_special_use(
55        &self,
56        id: &MailboxId,
57        special_use: SpecialUseAttributes,
58    ) -> anyhow::Result<()> {
59        // Default implementation does nothing
60        let _ = (id, special_use);
61        Ok(())
62    }
63
64    /// List mailboxes with a specific special-use attribute
65    async fn list_mailboxes_by_special_use(
66        &self,
67        user: &Username,
68        special_use: &str,
69    ) -> anyhow::Result<Vec<Mailbox>> {
70        // Default implementation filters all mailboxes
71        let mailboxes = self.list_mailboxes(user).await?;
72        let mut result = Vec::new();
73        for mailbox in mailboxes {
74            let attrs = self.get_mailbox_special_use(mailbox.id()).await?;
75            if attrs.has_attribute(special_use) {
76                result.push(mailbox);
77            }
78        }
79        Ok(result)
80    }
81
82    /// Subscribe to a mailbox
83    async fn subscribe_mailbox(&self, user: &Username, mailbox_name: String) -> anyhow::Result<()>;
84
85    /// Unsubscribe from a mailbox
86    async fn unsubscribe_mailbox(&self, user: &Username, mailbox_name: &str) -> anyhow::Result<()>;
87
88    /// List subscribed mailboxes
89    async fn list_subscriptions(&self, user: &Username) -> anyhow::Result<Vec<String>>;
90}
91
92/// Message storage operations
93#[async_trait]
94pub trait MessageStore: Send + Sync {
95    /// Append a message to a mailbox
96    async fn append_message(
97        &self,
98        mailbox_id: &MailboxId,
99        message: Mail,
100    ) -> anyhow::Result<MessageMetadata>;
101
102    /// Get a message by ID
103    async fn get_message(&self, message_id: &MessageId) -> anyhow::Result<Option<Mail>>;
104
105    /// Delete messages
106    async fn delete_messages(&self, message_ids: &[MessageId]) -> anyhow::Result<()>;
107
108    /// Set flags on messages
109    async fn set_flags(&self, message_ids: &[MessageId], flags: MessageFlags)
110        -> anyhow::Result<()>;
111
112    /// Search messages in a mailbox
113    async fn search(
114        &self,
115        mailbox_id: &MailboxId,
116        criteria: SearchCriteria,
117    ) -> anyhow::Result<Vec<MessageId>>;
118
119    /// Copy messages to another mailbox
120    async fn copy_messages(
121        &self,
122        message_ids: &[MessageId],
123        dest_mailbox_id: &MailboxId,
124    ) -> anyhow::Result<Vec<MessageMetadata>>;
125
126    /// Get all message metadata for a mailbox
127    async fn get_mailbox_messages(
128        &self,
129        mailbox_id: &MailboxId,
130    ) -> anyhow::Result<Vec<MessageMetadata>>;
131}
132
133/// Metadata storage operations
134#[async_trait]
135pub trait MetadataStore: Send + Sync {
136    /// Get user quota
137    async fn get_user_quota(&self, user: &Username) -> anyhow::Result<Quota>;
138
139    /// Set user quota
140    async fn set_user_quota(&self, user: &Username, quota: Quota) -> anyhow::Result<()>;
141
142    /// Get mailbox counters
143    async fn get_mailbox_counters(&self, mailbox_id: &MailboxId)
144        -> anyhow::Result<MailboxCounters>;
145}
146
147/// Combined storage backend
148pub trait StorageBackend: Send + Sync {
149    /// Get mailbox store
150    fn mailbox_store(&self) -> Arc<dyn MailboxStore>;
151
152    /// Get message store
153    fn message_store(&self) -> Arc<dyn MessageStore>;
154
155    /// Get metadata store
156    fn metadata_store(&self) -> Arc<dyn MetadataStore>;
157}