/* * libjmap * * Copyright 2019 Manos Pitsidianakis * * This file is part of libjmap. * * libjmap is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libjmap is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with libjmap. If not, see . */ use super::*; use serde::Serialize; use serde_json::Value; pub type UtcDate = String; use super::rfc8620::Object; macro_rules! get_request_no { ($lock:expr) => {{ let mut lck = $lock.lock().unwrap(); let ret = *lck; *lck += 1; ret }}; } pub trait Response { const NAME: &'static str; } pub trait Method: Serialize { const NAME: &'static str; } static USING: &[&str] = &["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"]; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct Request { using: &'static [&'static str], /* Why is this Value instead of Box>? The Method trait cannot be made into a * Trait object because its serialize() will be generic. */ method_calls: Vec, #[serde(skip)] request_no: Arc>, } impl Request { pub fn new(request_no: Arc>) -> Self { Request { using: USING, method_calls: Vec::new(), request_no, } } pub fn add_call, O: Object>(&mut self, call: &M) -> usize { let seq = get_request_no!(self.request_no); self.method_calls .push(serde_json::to_value((M::NAME, call, &format!("m{}", seq))).unwrap()); seq } } #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct JsonResponse<'a> { #[serde(borrow)] method_responses: Vec>, }