diff options
| author | Jakub Stachurski <jakub@wilkuu.nl> | 2026-09-19 23:43:04 +0200 |
|---|---|---|
| committer | Jakub Stachurski <jakub@wilkuu.nl> | 2026-09-19 23:43:04 +0200 |
| commit | 2b5caa2b306dc6a8c873f9ae3a2e0830cfbe5765 (patch) | |
| tree | 246514bc1d0580e73c4ae6fd38be6db91d12de6d /src/capabilities.rs | |
| parent | 0922d158f34d92929a485ba235a7e3a5e222153d (diff) | |
Add parsing of a JMAP request
Also adds:
- MethodRegistry to Capability and CapabilityRegistry
- Better parsing for JMAPId
- Eq and PartialEq for dates
- Tests for JMAPRequest
- Core/Echo method
- Support for Invocations
Diffstat (limited to 'src/capabilities.rs')
| -rw-r--r-- | src/capabilities.rs | 62 |
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); |
