1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use common::Server;
use jmap_proto::{
method::get::{GetRequest, GetResponse, RequestArguments},
object::Object,
request::reference::MaybeReference,
types::{any_id::AnyId, collection::Collection, id::Id, property::Property, value::Value},
};
use std::future::Future;
use store::query::Filter;
use crate::{changes::state::StateManager, JmapMethods};
pub trait VacationResponseGet: Sync + Send {
fn vacation_response_get(
&self,
request: GetRequest<RequestArguments>,
) -> impl Future<Output = trc::Result<GetResponse>> + Send;
fn get_vacation_sieve_script_id(
&self,
account_id: u32,
) -> impl Future<Output = trc::Result<Option<u32>>> + Send;
}
impl VacationResponseGet for Server {
async fn vacation_response_get(
&self,
mut request: GetRequest<RequestArguments>,
) -> trc::Result<GetResponse> {
let account_id = request.account_id.document_id();
let properties = request.unwrap_properties(&[
Property::Id,
Property::IsEnabled,
Property::FromDate,
Property::ToDate,
Property::Subject,
Property::TextBody,
Property::HtmlBody,
]);
let mut response = GetResponse {
account_id: request.account_id.into(),
state: self
.get_state(account_id, Collection::SieveScript)
.await?
.into(),
list: Vec::with_capacity(1),
not_found: vec![],
};
let do_get = if let Some(MaybeReference::Value(ids)) = request.ids {
let mut do_get = false;
for id in ids {
match id.try_unwrap() {
Some(AnyId::Id(id)) if id.is_singleton() => {
do_get = true;
}
Some(id) => {
response.not_found.push(id);
}
_ => {}
}
}
do_get
} else {
true
};
if do_get {
if let Some(document_id) = self.get_vacation_sieve_script_id(account_id).await? {
if let Some(mut obj) = self
.get_property::<Object<Value>>(
account_id,
Collection::SieveScript,
document_id,
Property::Value,
)
.await?
{
let mut result = Object::with_capacity(properties.len());
for property in &properties {
match property {
Property::Id => {
result.append(Property::Id, Value::Id(Id::singleton()));
}
Property::IsEnabled => {
result.append(Property::IsEnabled, obj.remove(&Property::IsActive));
}
Property::FromDate
| Property::ToDate
| Property::Subject
| Property::TextBody
| Property::HtmlBody => {
result.append(property.clone(), obj.remove(property));
}
property => {
result.append(property.clone(), Value::Null);
}
}
}
response.list.push(result);
} else {
response.not_found.push(Id::singleton().into());
}
} else {
response.not_found.push(Id::singleton().into());
}
}
Ok(response)
}
async fn get_vacation_sieve_script_id(&self, account_id: u32) -> trc::Result<Option<u32>> {
self.filter(
account_id,
Collection::SieveScript,
vec![Filter::eq(Property::Name, "vacation")],
)
.await
.map(|r| r.results.min())
}
}
|