use serde::{Serialize, Deserialize};
use std::{fs, process};
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub server: Server,
pub appservice: AppService,
pub matrix: Matrix,
pub redis: Redis,
pub cache: Cache,
pub public_rooms: PublicRooms,
pub spaces: Spaces,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Server {
pub port: u16,
pub allow_origin: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppService {
pub id: String,
pub sender_localpart: String,
pub access_token: String,
pub hs_access_token: String,
pub rules: AppServiceRules,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppServiceRules {
pub auto_join: bool,
pub invite_by_local_user: bool,
pub federation_domain_whitelist: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Matrix {
pub homeserver: String,
pub server_name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Redis {
pub url: String,
#[serde(default = "default_pool_size")]
pub pool_size: u32,
#[serde(default = "default_timeout_secs")]
pub timeout_secs: u64,
#[serde(default = "default_cache_ttl")]
pub cache_ttl: u64,
}
fn default_pool_size() -> u32 {
10
}
fn default_timeout_secs() -> u64 {
5
}
fn default_cache_ttl() -> u64 {
300
}
fn default_false() -> bool {
false
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Cache {
pub requests: CacheOptions,
pub public_rooms: CacheOptions,
pub room_state: CacheOptions,
pub messages: CacheOptions,
pub media: CacheOptions,
pub search: CacheOptions,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheOptions {
#[serde(default = "default_false")]
pub enabled: bool,
#[serde(default = "default_cache_ttl")]
pub expire_after: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PublicRooms {
pub curated: bool,
pub include_rooms: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Spaces {
pub default: Vec<String>,
pub cache: bool,
pub ttl: u64,
}
impl Default for Spaces {
fn default() -> Self {
Spaces {
default: Vec::new(),
cache: false,
ttl: 3600,
}
}
}
impl Config {
pub fn new(path: impl AsRef<Path>) -> Self {
let path = path.as_ref();
let config_content = match fs::read_to_string(path) {
Ok(content) => content,
Err(e) => {
tracing::info!("Failed to read config.toml: {}", e);
process::exit(1);
}
};
match toml::from_str(&config_content) {
Ok(config) => config,
Err(e) => {
tracing::info!("Failed to parse config.toml: {}", e);
process::exit(1);
}
}
}
}