refactor appservice type stuff

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
Matthias Ahouansou 2024-03-22 19:21:51 -04:00 committed by June
parent 7c9c5b1d78
commit 60f2471f59
11 changed files with 125 additions and 133 deletions

View file

@ -1,8 +1,9 @@
mod data;
use std::collections::HashMap;
use std::collections::BTreeMap;
pub(crate) use data::Data;
use futures_util::Future;
use regex::RegexSet;
use ruma::api::appservice::{Namespace, Registration};
use tokio::sync::RwLock;
@ -10,6 +11,7 @@ use tokio::sync::RwLock;
use crate::{services, Result};
/// Compiled regular expressions for a namespace
#[derive(Clone, Debug)]
pub struct NamespaceRegex {
pub exclusive: Option<RegexSet>,
pub non_exclusive: Option<RegexSet>,
@ -71,7 +73,8 @@ impl TryFrom<Vec<Namespace>> for NamespaceRegex {
}
}
/// Compiled regular expressions for an appservice
/// Appservice registration combined with its compiled regular expressions.
#[derive(Clone, Debug)]
pub struct RegistrationInfo {
pub registration: Registration,
pub users: NamespaceRegex,
@ -94,10 +97,26 @@ impl TryFrom<Registration> for RegistrationInfo {
pub struct Service {
pub db: &'static dyn Data,
pub registration_info: RwLock<HashMap<String, RegistrationInfo>>,
registration_info: RwLock<BTreeMap<String, RegistrationInfo>>,
}
impl Service {
pub fn build(db: &'static dyn Data) -> Result<Self> {
let mut registration_info = BTreeMap::new();
// Inserting registrations into cache
for appservice in db.all()? {
registration_info.insert(
appservice.0,
appservice.1.try_into().expect("Should be validated on registration"),
);
}
Ok(Self {
db,
registration_info: RwLock::new(registration_info),
})
}
/// Registers an appservice and returns the ID to the caller
pub async fn register_appservice(&self, yaml: Registration) -> Result<String> {
services().appservice.registration_info.write().await.insert(yaml.id.clone(), yaml.clone().try_into()?);
@ -116,9 +135,17 @@ impl Service {
self.db.unregister_appservice(service_name)
}
pub fn get_registration(&self, id: &str) -> Result<Option<Registration>> { self.db.get_registration(id) }
pub async fn get_registration(&self, id: &str) -> Option<Registration> {
self.registration_info.read().await.get(id).cloned().map(|info| info.registration)
}
pub fn iter_ids(&self) -> Result<impl Iterator<Item = Result<String>> + '_> { self.db.iter_ids() }
pub async fn iter_ids(&self) -> Vec<String> { self.registration_info.read().await.keys().cloned().collect() }
pub fn all(&self) -> Result<Vec<(String, Registration)>> { self.db.all() }
pub async fn find_from_token(&self, token: &str) -> Option<RegistrationInfo> {
self.read().await.values().find(|info| info.registration.as_token == token).cloned()
}
pub fn read(&self) -> impl Future<Output = tokio::sync::RwLockReadGuard<'_, BTreeMap<String, RegistrationInfo>>> {
self.registration_info.read()
}
}