onechatsocial_config/
lib.rs

1use std::collections::HashMap;
2
3use cached::proc_macro::cached;
4use config::{Config, File, FileFormat};
5use futures_locks::RwLock;
6use once_cell::sync::Lazy;
7use serde::Deserialize;
8
9static CONFIG_BUILDER: Lazy<RwLock<Config>> = Lazy::new(|| {
10    RwLock::new({
11        let mut builder = Config::builder().add_source(File::from_str(
12            include_str!("../Revolt.toml"),
13            FileFormat::Toml,
14        ));
15
16        if std::env::var("TEST_DB").is_ok() {
17            builder = builder.add_source(File::from_str(
18                include_str!("../Revolt.test.toml"),
19                FileFormat::Toml,
20            ));
21        } else if std::path::Path::new("Revolt.toml").exists() {
22            builder = builder.add_source(File::new("Revolt.toml", FileFormat::Toml));
23        }
24
25        builder.build().unwrap()
26    })
27});
28
29// https://gifbox.me/view/gT5mqxYKCZv-twilight-meow
30
31#[derive(Deserialize, Debug, Clone)]
32pub struct Database {
33    pub mongodb: String,
34    pub redis: String,
35}
36
37#[derive(Deserialize, Debug, Clone)]
38pub struct Hosts {
39    pub app: String,
40    pub api: String,
41    pub events: String,
42    pub autumn: String,
43    pub january: String,
44    pub voso_legacy: String,
45    pub voso_legacy_ws: String,
46}
47
48#[derive(Deserialize, Debug, Clone)]
49pub struct ApiRegistration {
50    pub invite_only: bool,
51}
52
53#[derive(Deserialize, Debug, Clone)]
54pub struct ApiSmtp {
55    pub host: String,
56    pub username: String,
57    pub password: String,
58    pub from_address: String,
59}
60
61#[derive(Deserialize, Debug, Clone)]
62pub struct ApiVapid {
63    pub private_key: String,
64    pub public_key: String,
65}
66
67#[derive(Deserialize, Debug, Clone)]
68pub struct ApiFcm {
69    pub api_key: String,
70}
71
72#[derive(Deserialize, Debug, Clone)]
73pub struct ApiSecurityCaptcha {
74    pub hcaptcha_key: String,
75    pub hcaptcha_sitekey: String,
76}
77
78#[derive(Deserialize, Debug, Clone)]
79pub struct ApiSecurity {
80    pub authifier_shield_key: String,
81    pub voso_legacy_token: String,
82    pub captcha: ApiSecurityCaptcha,
83}
84
85#[derive(Deserialize, Debug, Clone)]
86pub struct ApiWorkers {
87    pub max_concurrent_connections: usize,
88}
89
90#[derive(Deserialize, Debug, Clone)]
91pub struct Api {
92    pub staging: bool,
93    pub registration: ApiRegistration,
94    pub smtp: ApiSmtp,
95    pub vapid: ApiVapid,
96    pub fcm: ApiFcm,
97    pub security: ApiSecurity,
98    pub workers: ApiWorkers,
99}
100
101#[derive(Deserialize, Debug, Clone)]
102pub struct FeaturesLimits {
103    pub group_size: usize,
104    pub bots: usize,
105    pub message_length: usize,
106    pub message_replies: usize,
107    pub message_attachments: usize,
108    pub message_embeds: usize,
109    pub message_reactions: usize,
110    pub servers: usize,
111    pub server_emoji: usize,
112    pub server_roles: usize,
113    pub server_channels: usize,
114
115    pub attachment_size: usize,
116    pub avatar_size: usize,
117    pub background_size: usize,
118    pub icon_size: usize,
119    pub banner_size: usize,
120    pub emoji_size: usize,
121}
122
123#[derive(Deserialize, Debug, Clone)]
124pub struct FeaturesLimitsCollection {
125    pub default: FeaturesLimits,
126
127    #[serde(flatten)]
128    pub roles: HashMap<String, FeaturesLimits>,
129}
130
131#[derive(Deserialize, Debug, Clone)]
132pub struct Features {
133    pub limits: FeaturesLimitsCollection,
134}
135
136#[derive(Deserialize, Debug, Clone)]
137pub struct Settings {
138    pub database: Database,
139    pub hosts: Hosts,
140    pub api: Api,
141    pub features: Features,
142}
143
144pub async fn init() {
145    println!(
146        ":: Revolt Configuration ::\n\x1b[32m{:?}\x1b[0m",
147        config().await
148    );
149}
150
151pub async fn read() -> Config {
152    CONFIG_BUILDER.read().await.clone()
153}
154
155#[cached(time = 30)]
156pub async fn config() -> Settings {
157    read().await.try_deserialize::<Settings>().unwrap()
158}
159
160#[cfg(feature = "test")]
161#[cfg(test)]
162mod tests {
163    use crate::init;
164
165    #[async_std::test]
166    async fn it_works() {
167        init().await;
168    }
169}