melib/jmap: save all core capabilities to session store

We will need this in the future when we're going to support extra
extensions like Blob and also now to support server submission.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/279/head
Manos Pitsidianakis 2023-08-28 14:25:21 +03:00
parent 11432ba2c3
commit d9467d5fcd
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
3 changed files with 28 additions and 21 deletions

View File

@ -184,8 +184,6 @@ impl JmapConnection {
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
return Err(err);
}
*self.store.core_capabilities.lock().unwrap() =
session.capabilities[JMAP_CORE_CAPABILITY].clone();
if !session.capabilities.contains_key(JMAP_MAIL_CAPABILITY) {
let err = Error::new(format!(
"Server {} does not support JMAP Mail capability ({mail_capability}). Returned \
@ -202,6 +200,7 @@ impl JmapConnection {
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
return Err(err);
}
*self.store.core_capabilities.lock().unwrap() = session.capabilities.clone();
*self.store.online_status.lock().await = (Instant::now(), Ok(()));
*self.session.lock().unwrap() = session;

View File

@ -68,6 +68,7 @@ macro_rules! _impl {
pub const JMAP_CORE_CAPABILITY: &str = "urn:ietf:params:jmap:core";
pub const JMAP_MAIL_CAPABILITY: &str = "urn:ietf:params:jmap:mail";
pub const JMAP_SUBMISSION_CAPABILITY: &str = "urn:ietf:params:jmap:submission";
pub mod operations;
use operations::*;
@ -196,7 +197,7 @@ pub struct Store {
pub mailbox_state: Arc<Mutex<State<MailboxObject>>>,
pub online_status: Arc<FutureMutex<(Instant, Result<()>)>>,
pub is_subscribed: Arc<IsSubscribedFn>,
pub core_capabilities: Arc<Mutex<rfc8620::CapabilitiesObject>>,
pub core_capabilities: Arc<Mutex<IndexMap<String, rfc8620::CapabilitiesObject>>>,
pub event_consumer: BackendEventConsumer,
}
@ -292,9 +293,18 @@ impl MailBackend for JmapType {
supports_search: true,
extensions: None,
supports_tags: true,
supports_submission: false,
supports_submission: true,
};
CAPABILITIES
let supports_submission: bool = self
.store
.core_capabilities
.lock()
.map(|c| c.contains_key(JMAP_SUBMISSION_CAPABILITY))
.unwrap_or(false);
MailBackendCapabilities {
supports_submission: CAPABILITIES.supports_submission || supports_submission,
..CAPABILITIES
}
}
fn is_online(&self) -> ResultFuture<()> {
@ -322,7 +332,7 @@ impl MailBackend for JmapType {
Ok(Box::pin(async_stream::try_stream! {
let mut conn = connection.lock().await;
conn.connect().await?;
let batch_size: u64 = conn.store.core_capabilities.lock().unwrap().max_objects_in_get;
let batch_size: u64 = conn.store.core_capabilities.lock().unwrap()[JMAP_CORE_CAPABILITY].max_objects_in_get;
let mut fetch_state = protocol::EmailFetchState::Start { batch_size };
loop {
let res = fetch_state.fetch(
@ -384,7 +394,7 @@ impl MailBackend for JmapType {
let mut conn = connection.lock().await;
conn.connect().await?;
if store.mailboxes.read().unwrap().is_empty() {
let new_mailboxes = debug!(protocol::get_mailboxes(&mut conn).await)?;
let new_mailboxes = debug!(protocol::get_mailboxes(&mut conn, None).await)?;
*store.mailboxes.write().unwrap() = new_mailboxes;
}
@ -488,7 +498,7 @@ impl MailBackend for JmapType {
}
})?;
if let Some(err) = m.not_created.get(&creation_id) {
if let Some(err) = m.not_created.and_then(|m| m.get(&creation_id).cloned()) {
return Err(Error::new(format!("Could not save message: {:?}", err)));
}
Ok(())
@ -894,7 +904,7 @@ impl JmapType {
event_consumer,
is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
collection: Collection::default(),
core_capabilities: Arc::new(Mutex::new(rfc8620::CapabilitiesObject::default())),
core_capabilities: Arc::new(Mutex::new(IndexMap::default())),
byte_cache: Default::default(),
id_store: Default::default(),
reverse_id_store: Default::default(),

View File

@ -22,7 +22,7 @@
use std::convert::{TryFrom, TryInto};
use serde::Serialize;
use serde_json::{json, Value};
use serde_json::Value;
use super::{mailbox::JmapMailbox, *};
@ -78,17 +78,15 @@ impl Request {
}
}
pub async fn get_mailboxes(conn: &mut JmapConnection) -> Result<HashMap<MailboxHash, JmapMailbox>> {
let seq = get_request_no!(conn.request_no);
let res_text = conn
.send_request(serde_json::to_string(&json!({
"using": [JMAP_CORE_CAPABILITY, JMAP_MAIL_CAPABILITY],
"methodCalls": [["Mailbox/get", {
"accountId": conn.mail_account_id()
},
format!("#m{}",seq).as_str()]],
}))?)
.await?;
pub async fn get_mailboxes(
conn: &mut JmapConnection,
request: Option<Request>,
) -> Result<HashMap<MailboxHash, JmapMailbox>> {
let mut req = request.unwrap_or_else(|| Request::new(conn.request_no.clone()));
let mailbox_get: MailboxGet =
MailboxGet::new(Get::<MailboxObject>::new().account_id(conn.mail_account_id()));
req.add_call(&mailbox_get);
let res_text = conn.send_request(serde_json::to_string(&req)?).await?;
let mut v: MethodResponse = deserialize_from_str(&res_text)?;
*conn.store.online_status.lock().await = (std::time::Instant::now(), Ok(()));