async_imap/extensions/
quota.rs1use 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}