summaryrefslogtreecommitdiff
path: root/src/capabilities.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/capabilities.rs62
1 files changed, 57 insertions, 5 deletions
diff --git a/src/capabilities.rs b/src/capabilities.rs
index 63aa6e8..1a4aa35 100644
--- a/src/capabilities.rs
+++ b/src/capabilities.rs
@@ -1,8 +1,11 @@
use std::any::Any;
use std::collections::BTreeMap;
+use std::sync::Arc;
+use lazy_static;
use serde::{Deserialize, Serialize};
+use crate::request::{JMAPInvocationArg, MethodRegistry};
use crate::session::ISession;
use crate::*;
@@ -10,11 +13,27 @@ use crate::*;
/// JMAP Core URN
pub const URN_JMAP_CORE: &str = "urn:ietf:params:jmap:core";
+lazy_static::lazy_static! {
+ static ref JMAP_CORE_METHODS: MethodRegistry = {
+ let mut reg = MethodRegistry::new();
+ reg.add_method::<CoreEchoArgs>();
+ reg
+ };
+
+ static ref DEFAULT_METHODS_REG: MethodRegistry = {
+ MethodRegistry::new()
+ };
+}
// Capabilities {{{
+//
pub trait Capability: 'static + Sized {
const URN: &str;
+ fn get_methods() -> &'static MethodRegistry {
+ &DEFAULT_METHODS_REG
+ }
+
fn from_object(obj: &JObject) -> Self;
fn account_cap(&self, account_id: JMAPId, obj: &JObject) -> Self;
fn account(&self) -> Option<JMAPId>;
@@ -75,8 +94,14 @@ impl<T: Capability> CapabilityDyn for T {
/// A function that parses a JObject into a Capability Trait object.
/// This capability will be able to implement functionality to the JMAPSession object.
pub type CapabilityParser = Box<dyn Fn(&JObject) -> Box<dyn CapabilityDyn>>;
+
+pub struct CapabilityEntry {
+ pub(crate) parser: CapabilityParser,
+ pub(crate) methods: &'static MethodRegistry,
+}
+
/// Collection of CapabilityParser
-pub struct CapabilityRegistry(pub BTreeMap<String, CapabilityParser>);
+pub struct CapabilityRegistry(pub BTreeMap<String, CapabilityEntry>);
impl Default for CapabilityRegistry {
fn default() -> Self {
@@ -94,16 +119,21 @@ impl CapabilityRegistry {
/// Insert a parser
pub fn add_capability<T: Capability>(&mut self) {
- self.0
- .insert(T::URN.to_string(), Box::new(T::from_object_dyn));
+ self.0.insert(
+ T::URN.to_string(),
+ CapabilityEntry {
+ parser: Box::new(T::from_object_dyn),
+ methods: T::get_methods(),
+ },
+ );
}
/// Use the parsers to create a list of capabilities supported by the server in the session.
pub fn server_capabilities(&self, session: &ISession) -> ServerCapabilities {
let mut out = BTreeMap::new();
for (urn, cap) in session.capabilities.iter() {
- if let Some(parser) = self.0.get(urn) {
- out.insert(urn.clone(), parser(cap));
+ if let Some(entry) = self.0.get(urn) {
+ out.insert(urn.clone(), (entry.parser)(cap));
};
}
ServerCapabilities(out)
@@ -192,6 +222,24 @@ impl CapabilityCollection for AccountCapabilities {
// }}}
/// JMAP Core capability as outlined in RFC 8620
+pub struct CoreEchoArgs {
+ pub obj: JObject,
+}
+
+impl JMAPInvocationArg for CoreEchoArgs {
+ const CAP_URN: &str = URN_JMAP_CORE;
+
+ const METHOD_HINT: &str = "Core/Echo";
+
+ fn from_obj(obj: &JObject) -> Self {
+ Self { obj: obj.clone() }
+ }
+
+ fn into_obj(self) -> JObject {
+ self.obj
+ }
+}
+
#[allow(non_snake_case)]
#[derive(Serialize, Deserialize, Clone)]
pub struct JMAPCoreCapability {
@@ -216,6 +264,10 @@ impl Capability for JMAPCoreCapability {
out
}
+ fn get_methods() -> &'static MethodRegistry {
+ &JMAP_CORE_METHODS
+ }
+
fn account_cap(&self, account_id: JMAPId, _: &JObject) -> Self {
let mut out = self.clone();
out.accountId = Some(account_id);