Skip to main content

opentalk_client_data_persistence/
config.rs

1// SPDX-FileCopyrightText: OpenTalk GmbH <mail@opentalk.eu>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5use std::collections::BTreeMap;
6
7use serde::{Deserialize, Serialize};
8
9use crate::{
10    OpenTalkAccountConfig, OpenTalkAccountId, OpenTalkInstanceAccountId, OpenTalkInstanceId,
11    opentalk_instance_config::OpenTalkInstanceConfig,
12};
13
14/// Config to store needable state of the opentalk client
15#[derive(Debug, Clone, PartialEq, Eq, Default, Deserialize, Serialize)]
16pub struct Config {
17    /// Default OpenTalk instance
18    #[serde(default, skip_serializing_if = "Option::is_none")]
19    pub default_instance: Option<OpenTalkInstanceId>,
20
21    /// OpenTalk instances
22    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
23    pub instances: BTreeMap<OpenTalkInstanceId, OpenTalkInstanceConfig>,
24}
25
26impl Config {
27    /// Get the default instance if available.
28    pub fn get_default_instance(&self) -> Option<(OpenTalkInstanceId, OpenTalkInstanceConfig)> {
29        let instance_id = self.default_instance.clone()?;
30        let instance = self.get_instance(&instance_id)?.clone();
31        Some((instance_id, instance))
32    }
33
34    /// Get an instance by its [OpenTalkInstanceId].
35    pub fn get_instance(&self, instance_id: &OpenTalkInstanceId) -> Option<OpenTalkInstanceConfig> {
36        self.instances.get(instance_id).cloned()
37    }
38
39    /// Get the default account if available.
40    ///
41    /// This will return the default account of the default instance.
42    pub fn get_default_account(
43        &self,
44    ) -> Option<(OpenTalkInstanceAccountId, OpenTalkAccountConfig)> {
45        let (instance_id, instance) = self.get_default_instance()?;
46
47        let (account_id, account) = instance.get_default_account()?;
48
49        Some(((instance_id.clone(), account_id).into(), account))
50    }
51
52    /// Get an instance config by an optional id, returning the default config if the id is [None].
53    pub fn get_instance_with_fallback_to_default(
54        &self,
55        instance_id: Option<&OpenTalkInstanceId>,
56    ) -> Option<(OpenTalkInstanceId, OpenTalkInstanceConfig)> {
57        if let Some(instance_id) = instance_id {
58            let instance = self.get_instance(instance_id)?;
59            Some((instance_id.clone(), instance.clone()))
60        } else {
61            self.get_default_instance()
62        }
63    }
64
65    /// Get an account config by optional ids, returning the default config at each level if the ids are [None].
66    pub fn get_account_with_fallback_to_default(
67        &self,
68        instance_id: Option<&OpenTalkInstanceId>,
69        account_id: Option<&OpenTalkAccountId>,
70    ) -> Option<(OpenTalkInstanceAccountId, OpenTalkAccountConfig)> {
71        let (instance_id, instance) = self.get_instance_with_fallback_to_default(instance_id)?;
72        let (account_id, account) = instance.get_account_with_fallback_to_default(account_id)?;
73        Some(((instance_id, account_id).into(), account))
74    }
75
76    /// Remove an account from the configuration.
77    pub fn remove_account(
78        &mut self,
79        instance_id: Option<&OpenTalkInstanceId>,
80        account_id: Option<&OpenTalkAccountId>,
81    ) {
82        let Some(instance_id) = self.default_instance.as_ref().or(instance_id) else {
83            return;
84        };
85
86        let Some(instance) = self.instances.get_mut(instance_id) else {
87            return;
88        };
89
90        instance.remove_account(account_id);
91    }
92}