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 10 months ago
parent 11432ba2c3
commit d9467d5fcd
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

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

@ -68,6 +68,7 @@ macro_rules! _impl {
pub const JMAP_CORE_CAPABILITY: &str = "urn:ietf:params:jmap:core"; 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_MAIL_CAPABILITY: &str = "urn:ietf:params:jmap:mail";
pub const JMAP_SUBMISSION_CAPABILITY: &str = "urn:ietf:params:jmap:submission";
pub mod operations; pub mod operations;
use operations::*; use operations::*;
@ -196,7 +197,7 @@ pub struct Store {
pub mailbox_state: Arc<Mutex<State<MailboxObject>>>, pub mailbox_state: Arc<Mutex<State<MailboxObject>>>,
pub online_status: Arc<FutureMutex<(Instant, Result<()>)>>, pub online_status: Arc<FutureMutex<(Instant, Result<()>)>>,
pub is_subscribed: Arc<IsSubscribedFn>, 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, pub event_consumer: BackendEventConsumer,
} }
@ -292,9 +293,18 @@ impl MailBackend for JmapType {
supports_search: true, supports_search: true,
extensions: None, extensions: None,
supports_tags: true, 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<()> { fn is_online(&self) -> ResultFuture<()> {
@ -322,7 +332,7 @@ impl MailBackend for JmapType {
Ok(Box::pin(async_stream::try_stream! { Ok(Box::pin(async_stream::try_stream! {
let mut conn = connection.lock().await; let mut conn = connection.lock().await;
conn.connect().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 }; let mut fetch_state = protocol::EmailFetchState::Start { batch_size };
loop { loop {
let res = fetch_state.fetch( let res = fetch_state.fetch(
@ -384,7 +394,7 @@ impl MailBackend for JmapType {
let mut conn = connection.lock().await; let mut conn = connection.lock().await;
conn.connect().await?; conn.connect().await?;
if store.mailboxes.read().unwrap().is_empty() { 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; *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))); return Err(Error::new(format!("Could not save message: {:?}", err)));
} }
Ok(()) Ok(())
@ -894,7 +904,7 @@ impl JmapType {
event_consumer, event_consumer,
is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)), is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
collection: Collection::default(), collection: Collection::default(),
core_capabilities: Arc::new(Mutex::new(rfc8620::CapabilitiesObject::default())), core_capabilities: Arc::new(Mutex::new(IndexMap::default())),
byte_cache: Default::default(), byte_cache: Default::default(),
id_store: Default::default(), id_store: Default::default(),
reverse_id_store: Default::default(), reverse_id_store: Default::default(),

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

Loading…
Cancel
Save