async_imap/extensions/
quota.rs

1//! Adds support for the GETQUOTA and GETQUOTAROOT commands specificed in [RFC2087](https://tools.ietf.org/html/rfc2087).
2
3use async_channel as channel;
4use futures::io;
5use futures::prelude::*;
6use imap_proto::{self, RequestId, Response};
7
8use crate::types::*;
9use crate::{
10    error::Result,
11    parse::{filter, handle_unilateral},
12};
13use crate::{
14    error::{Error, ParseError},
15    types::{Quota, QuotaRoot, ResponseData},
16};
17
18pub(crate) async fn parse_get_quota<T: Stream<Item = io::Result<ResponseData>> + Unpin>(
19    stream: &mut T,
20    unsolicited: channel::Sender<UnsolicitedResponse>,
21    command_tag: RequestId,
22) -> Result<Quota> {
23    let mut quota = None;
24    while let Some(resp) = stream
25        .take_while(|res| filter(res, &command_tag))
26        .try_next()
27        .await?
28    {
29        match resp.parsed() {
30            Response::Quota(q) => quota = Some(q.clone().into()),
31            _ => {
32                handle_unilateral(resp, unsolicited.clone());
33            }
34        }
35    }
36
37    match quota {
38        Some(q) => Ok(q),
39        None => Err(Error::Parse(ParseError::ExpectedResponseNotFound(
40            "Quota, no quota response found".to_string(),
41        ))),
42    }
43}
44
45pub(crate) async fn parse_get_quota_root<T: Stream<Item = io::Result<ResponseData>> + Unpin>(
46    stream: &mut T,
47    unsolicited: channel::Sender<UnsolicitedResponse>,
48    command_tag: RequestId,
49) -> Result<(Vec<QuotaRoot>, Vec<Quota>)> {
50    let mut roots: Vec<QuotaRoot> = Vec::new();
51    let mut quotas: Vec<Quota> = Vec::new();
52
53    while let Some(resp) = stream
54        .take_while(|res| filter(res, &command_tag))
55        .try_next()
56        .await?
57    {
58        match resp.parsed() {
59            Response::QuotaRoot(qr) => {
60                roots.push(qr.clone().into());
61            }
62            Response::Quota(q) => {
63                quotas.push(q.clone().into());
64            }
65            _ => {
66                handle_unilateral(resp, unsolicited.clone());
67            }
68        }
69    }
70
71    Ok((roots, quotas))
72}