conduit/src/database/appservice.rs

75 lines
2.3 KiB
Rust

use crate::{utils, Error, Result};
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use super::abstraction::Tree;
pub struct Appservice {
pub(super) cached_registrations: Arc<RwLock<HashMap<String, serde_yaml::Value>>>,
pub(super) id_appserviceregistrations: Arc<dyn Tree>,
}
impl Appservice {
pub fn register_appservice(&self, yaml: serde_yaml::Value) -> Result<()> {
// TODO: Rumaify
let id = yaml.get("id").unwrap().as_str().unwrap();
self.id_appserviceregistrations.insert(
id.as_bytes(),
serde_yaml::to_string(&yaml).unwrap().as_bytes(),
)?;
self.cached_registrations
.write()
.unwrap()
.insert(id.to_owned(), yaml);
Ok(())
}
pub fn get_registration(&self, id: &str) -> Result<Option<serde_yaml::Value>> {
self.cached_registrations
.read()
.unwrap()
.get(id)
.map_or_else(
|| {
Ok(self
.id_appserviceregistrations
.get(id.as_bytes())?
.map(|bytes| {
Ok::<_, Error>(serde_yaml::from_slice(&bytes).map_err(|_| {
Error::bad_database(
"Invalid registration bytes in id_appserviceregistrations.",
)
})?)
})
.transpose()?)
},
|r| Ok(Some(r.clone())),
)
}
pub fn iter_ids<'a>(
&'a self,
) -> Result<impl Iterator<Item = Result<String>> + Send + Sync + 'a> {
Ok(self.id_appserviceregistrations.iter().map(|(id, _)| {
Ok(utils::string_from_bytes(&id).map_err(|_| {
Error::bad_database("Invalid id bytes in id_appserviceregistrations.")
})?)
}))
}
pub fn iter_all(
&self,
) -> Result<impl Iterator<Item = Result<(String, serde_yaml::Value)>> + '_ + Send + Sync> {
Ok(self.iter_ids()?.filter_map(|id| id.ok()).map(move |id| {
Ok((
id.clone(),
self.get_registration(&id)?
.expect("iter_ids only returns appservices that exist"),
))
}))
}
}