async_imap/types/
quota.rs

1use imap_proto::types::Quota as QuotaRef;
2use imap_proto::types::QuotaResource as QuotaResourceRef;
3use imap_proto::types::QuotaResourceName as QuotaResourceNameRef;
4use imap_proto::types::QuotaRoot as QuotaRootRef;
5
6/// <https://tools.ietf.org/html/rfc2087#section-3>
7#[derive(Debug, Eq, PartialEq, Hash, Clone)]
8pub enum QuotaResourceName {
9    /// Sum of messages' RFC822.SIZE, in units of 1024 octets
10    Storage,
11    /// Number of messages
12    Message,
13    /// A different/custom resource
14    Atom(String),
15}
16
17impl From<QuotaResourceNameRef<'_>> for QuotaResourceName {
18    fn from(name: QuotaResourceNameRef<'_>) -> Self {
19        match name {
20            QuotaResourceNameRef::Message => QuotaResourceName::Message,
21            QuotaResourceNameRef::Storage => QuotaResourceName::Storage,
22            QuotaResourceNameRef::Atom(v) => QuotaResourceName::Atom(v.to_string()),
23        }
24    }
25}
26
27/// 5.1. QUOTA Response (<https://tools.ietf.org/html/rfc2087#section-5.1>)
28#[derive(Debug, Eq, PartialEq, Hash, Clone)]
29pub struct QuotaResource {
30    /// name of the resource
31    pub name: QuotaResourceName,
32    /// current usage of the resource
33    pub usage: u64,
34    /// resource limit
35    pub limit: u64,
36}
37
38impl From<QuotaResourceRef<'_>> for QuotaResource {
39    fn from(resource: QuotaResourceRef<'_>) -> Self {
40        Self {
41            name: resource.name.into(),
42            usage: resource.usage,
43            limit: resource.limit,
44        }
45    }
46}
47
48impl QuotaResource {
49    /// Returns the usage percentage of a QuotaResource.
50    pub fn get_usage_percentage(&self) -> u64 {
51        self.usage
52            .saturating_mul(100)
53            .checked_div(self.limit)
54            // Assume that if `limit` is 0, this means that storage is unlimited:
55            .unwrap_or(0)
56    }
57}
58
59/// 5.1. QUOTA Response (<https://tools.ietf.org/html/rfc2087#section-5.1>)
60#[derive(Debug, Eq, PartialEq, Hash, Clone)]
61pub struct Quota {
62    /// quota root name
63    pub root_name: String,
64    /// quota resources for this quota
65    pub resources: Vec<QuotaResource>,
66}
67
68impl From<QuotaRef<'_>> for Quota {
69    fn from(quota: QuotaRef<'_>) -> Self {
70        Self {
71            root_name: quota.root_name.to_string(),
72            resources: quota.resources.iter().map(|r| r.clone().into()).collect(),
73        }
74    }
75}
76
77/// 5.2. QUOTAROOT Response (<https://tools.ietf.org/html/rfc2087#section-5.2>)
78#[derive(Debug, Eq, PartialEq, Hash, Clone)]
79pub struct QuotaRoot {
80    /// mailbox name
81    pub mailbox_name: String,
82    /// zero or more quota root names
83    pub quota_root_names: Vec<String>,
84}
85
86impl From<QuotaRootRef<'_>> for QuotaRoot {
87    fn from(root: QuotaRootRef<'_>) -> Self {
88        Self {
89            mailbox_name: root.mailbox_name.to_string(),
90            quota_root_names: root
91                .quota_root_names
92                .iter()
93                .map(|n| n.to_string())
94                .collect(),
95        }
96    }
97}