summaryrefslogtreecommitdiff
path: root/src/database/key_value/appservice.rs
blob: f427ba71bb29ef3c9bcef0162d6b71afd3dd5e33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::{database::KeyValueDatabase, service, utils, Error, Result};

impl service::appservice::Data for KeyValueDatabase {
    /// Registers an appservice and returns the ID to the caller
    fn register_appservice(&self, yaml: serde_yaml::Value) -> Result<String> {
        // 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.to_owned());

        Ok(id.to_owned())
    }

    /// Remove an appservice registration
    ///
    /// # Arguments
    ///
    /// * `service_name` - the name you send to register the service previously
    fn unregister_appservice(&self, service_name: &str) -> Result<()> {
        self.id_appserviceregistrations
            .remove(service_name.as_bytes())?;
        self.cached_registrations
            .write()
            .unwrap()
            .remove(service_name);
        Ok(())
    }

    fn get_registration(&self, id: &str) -> Result<Option<serde_yaml::Value>> {
        self.cached_registrations
            .read()
            .unwrap()
            .get(id)
            .map_or_else(
                || {
                    self.id_appserviceregistrations
                        .get(id.as_bytes())?
                        .map(|bytes| {
                            serde_yaml::from_slice(&bytes).map_err(|_| {
                                Error::bad_database(
                                    "Invalid registration bytes in id_appserviceregistrations.",
                                )
                            })
                        })
                        .transpose()
                },
                |r| Ok(Some(r.clone())),
            )
    }

    fn iter_ids<'a>(&'a self) -> Result<Box<dyn Iterator<Item = Result<String>> + 'a>> {
        Ok(Box::new(self.id_appserviceregistrations.iter().map(|(id, _)| {
            utils::string_from_bytes(&id)
                .map_err(|_| Error::bad_database("Invalid id bytes in id_appserviceregistrations."))
        })))
    }

    fn all(&self) -> Result<Vec<(String, serde_yaml::Value)>> {
        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"),
                ))
            })
            .collect()
    }
}