summaryrefslogtreecommitdiff
path: root/crates/jmap/src/api/request.rs
blob: c1d696c9b26bd2c8a51040ce7fef6ba9501f1753 (plain)
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
use jmap_proto::{
    error::request::RequestError,
    method::{get, query, set},
    request::{method::MethodName, Request, RequestMethod},
    response::{Response, ResponseMethod},
};

use crate::JMAP;

impl JMAP {
    pub async fn handle_request(&self, bytes: &[u8]) -> Result<Response, RequestError> {
        let request = Request::parse(
            bytes,
            self.config.request_max_calls,
            self.config.request_max_size,
        )?;
        let mut response = Response::new(
            0,
            request.created_ids.unwrap_or_default(),
            request.method_calls.len(),
        );
        for mut call in request.method_calls {
            // Resolve result and id references
            if let Err(method_error) = response.resolve_references(&mut call.method) {
                response.push_response(call.id, MethodName::error(), method_error);
                continue;
            }

            let method_response: ResponseMethod = match call.method {
                RequestMethod::Get(mut req) => match req.take_arguments() {
                    get::RequestArguments::Email(arguments) => {
                        self.email_get(req.with_arguments(arguments)).await.into()
                    }
                    get::RequestArguments::Mailbox => self.mailbox_get(req).await.into(),
                    get::RequestArguments::Thread => self.thread_get(req).await.into(),
                    get::RequestArguments::Identity => todo!(),
                    get::RequestArguments::EmailSubmission => todo!(),
                    get::RequestArguments::PushSubscription => todo!(),
                    get::RequestArguments::SieveScript => todo!(),
                    get::RequestArguments::VacationResponse => todo!(),
                    get::RequestArguments::Principal => todo!(),
                },
                RequestMethod::Query(mut req) => match req.take_arguments() {
                    query::RequestArguments::Email(arguments) => {
                        self.email_query(req.with_arguments(arguments)).await.into()
                    }
                    query::RequestArguments::Mailbox(arguments) => self
                        .mailbox_query(req.with_arguments(arguments))
                        .await
                        .into(),
                    query::RequestArguments::EmailSubmission => todo!(),
                    query::RequestArguments::SieveScript => todo!(),
                    query::RequestArguments::Principal => todo!(),
                },
                RequestMethod::Set(mut req) => match req.take_arguments() {
                    set::RequestArguments::Email => self.email_set(req, &response).await.into(),
                    set::RequestArguments::Mailbox(arguments) => self
                        .mailbox_set(req.with_arguments(arguments), &response)
                        .await
                        .into(),
                    set::RequestArguments::Identity => todo!(),
                    set::RequestArguments::EmailSubmission(_) => todo!(),
                    set::RequestArguments::PushSubscription => todo!(),
                    set::RequestArguments::SieveScript(_) => todo!(),
                    set::RequestArguments::VacationResponse => todo!(),
                    set::RequestArguments::Principal => todo!(),
                },
                RequestMethod::Changes(_) => todo!(),
                RequestMethod::Copy(_) => todo!(),
                RequestMethod::CopyBlob(_) => todo!(),
                RequestMethod::ImportEmail(req) => self.email_import(req).await.into(),
                RequestMethod::ParseEmail(_) => todo!(),
                RequestMethod::QueryChanges(_) => todo!(),
                RequestMethod::SearchSnippet(_) => todo!(),
                RequestMethod::ValidateScript(_) => todo!(),
                RequestMethod::Echo(req) => req.into(),
                RequestMethod::Error(error) => error.into(),
            };

            response.push_response(
                call.id,
                if !matches!(method_response, ResponseMethod::Error(_)) {
                    call.name
                } else {
                    MethodName::error()
                },
                method_response,
            );
        }

        Ok(response)
    }
}