JMAP for Contacts implementation (part 2)
This commit is contained in:
@@ -402,6 +402,7 @@ impl AccessToken {
|
||||
s.finish() as u32
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn primary_id(&self) -> u32 {
|
||||
self.primary_id
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ pub struct JmapConfig {
|
||||
pub mail_max_size: usize,
|
||||
pub mail_autoexpunge_after: Option<u64>,
|
||||
|
||||
pub contact_parse_max_items: usize,
|
||||
|
||||
pub sieve_max_script_name: usize,
|
||||
pub sieve_max_scripts: usize,
|
||||
|
||||
@@ -337,6 +339,9 @@ impl JmapConfig {
|
||||
.value("authentication.master.secret")
|
||||
.map(|p| (u.to_string(), p.to_string()))
|
||||
}),
|
||||
contact_parse_max_items: config
|
||||
.property("jmap.contact.parse.max-items")
|
||||
.unwrap_or(100),
|
||||
default_folders,
|
||||
shared_folder,
|
||||
};
|
||||
|
||||
@@ -37,6 +37,7 @@ use std::{
|
||||
sync::{Arc, atomic::AtomicBool},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use store::rand::{Rng, distr::Alphanumeric};
|
||||
use tinyvec::TinyVec;
|
||||
use tokio::sync::{Notify, Semaphore, mpsc};
|
||||
use tokio_rustls::TlsConnector;
|
||||
@@ -575,6 +576,19 @@ impl DavResources {
|
||||
.find(|res| res.document_id == id && res.is_container())
|
||||
}
|
||||
|
||||
pub fn container_resource_path_by_id(&self, id: u32) -> Option<DavResourcePath<'_>> {
|
||||
self.resources
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, resource)| resource.document_id == id && resource.is_container())
|
||||
.and_then(|(idx, resource)| {
|
||||
self.paths
|
||||
.iter()
|
||||
.find(|path| path.resource_idx == idx)
|
||||
.map(|path| DavResourcePath { path, resource })
|
||||
})
|
||||
}
|
||||
|
||||
pub fn subtree(&self, search_path: &str) -> impl Iterator<Item = DavResourcePath<'_>> {
|
||||
let prefix = format!("{search_path}/");
|
||||
self.paths.iter().filter_map(move |path| {
|
||||
@@ -635,6 +649,13 @@ impl DavResources {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn children_ids(&self, parent_id: u32) -> impl Iterator<Item = u32> {
|
||||
self.paths
|
||||
.iter()
|
||||
.filter(move |item| item.parent_id.is_some_and(|id| id == parent_id))
|
||||
.map(|path| self.resources[path.resource_idx].document_id)
|
||||
}
|
||||
|
||||
pub fn format_resource(&self, resource: DavResourcePath<'_>) -> String {
|
||||
if resource.resource.is_container() {
|
||||
format!("{}{}/", self.base_path, resource.path.path)
|
||||
@@ -822,6 +843,17 @@ impl DavName {
|
||||
pub fn new(name: String, parent_id: u32) -> Self {
|
||||
Self { name, parent_id }
|
||||
}
|
||||
|
||||
pub fn new_with_rand_name(parent_id: u32) -> Self {
|
||||
Self {
|
||||
name: store::rand::rng()
|
||||
.sample_iter(Alphanumeric)
|
||||
.take(10)
|
||||
.map(char::from)
|
||||
.collect::<String>(),
|
||||
parent_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CacheSwap<T> {
|
||||
|
||||
@@ -90,4 +90,16 @@ impl DavResources {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn has_container_id(&self, id: &u32) -> bool {
|
||||
self.resources
|
||||
.iter()
|
||||
.any(|r| r.document_id == *id && r.is_container())
|
||||
}
|
||||
|
||||
pub fn has_item_id(&self, id: &u32) -> bool {
|
||||
self.resources
|
||||
.iter()
|
||||
.any(|r| r.document_id == *id && !r.is_container())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user