Game sync and live services for independent game developers (targeting itch.io)
1use config::{Config as ConfigLoader, File};
2use serde::Deserialize;
3use std::net::SocketAddr;
4
5#[derive(Debug, Deserialize, Clone)]
6pub struct AppConfig {
7 pub server: ServerConfig,
8 pub database: DatabaseConfig,
9 pub storage: StorageConfig,
10 pub auth: AuthConfig,
11 pub log_level: String,
12}
13
14#[derive(Debug, Deserialize, Clone)]
15pub struct ServerConfig {
16 pub host: String,
17 pub port: u16,
18}
19
20#[derive(Debug, Deserialize, Clone)]
21pub struct DatabaseConfig {
22 pub path: String,
23}
24
25#[derive(Debug, Deserialize, Clone)]
26pub struct StorageConfig {
27 pub provider: String,
28 pub do_spaces_endpoint: Option<String>,
29 pub do_spaces_bucket: Option<String>,
30 pub do_spaces_access_key: Option<String>,
31 pub do_spaces_secret_key: Option<String>,
32}
33
34#[derive(Debug, Deserialize, Clone)]
35pub struct AuthConfig {
36 pub jwt_secret: String,
37 pub itchio_client_id: String,
38 pub itchio_oauth_url: String,
39}
40
41impl AppConfig {
42 pub fn load() -> anyhow::Result<Self> {
43 let config = ConfigLoader::builder()
44 .add_source(File::with_name("config").required(false))
45 .add_source(File::with_name("/etc/scratchback/config").required(false))
46 .add_source(config::Environment::default())
47 .build()?;
48
49 let mut app_config: AppConfig = config.try_deserialize()?;
50
51 if let Ok(server_host) = std::env::var("SCRATCHBACK_HOST") {
52 app_config.server.host = server_host;
53 }
54 if let Ok(server_port) = std::env::var("SCRATCHBACK_PORT") {
55 if let Ok(port) = server_port.parse() {
56 app_config.server.port = port;
57 }
58 }
59
60 Ok(app_config)
61 }
62
63 pub fn server_addr(&self) -> SocketAddr {
64 format!("{}:{}", self.server.host, self.server.port)
65 .parse()
66 .unwrap_or_else(|_| SocketAddr::from(([0, 0, 0, 0], 3000)))
67 }
68}
69
70impl Default for AppConfig {
71 fn default() -> Self {
72 Self {
73 server: ServerConfig {
74 host: "0.0.0.0".to_string(),
75 port: 3000,
76 },
77 database: DatabaseConfig {
78 path: "/var/data/scratchback/scratchback.db".to_string(),
79 },
80 storage: StorageConfig {
81 provider: "local".to_string(),
82 do_spaces_endpoint: None,
83 do_spaces_bucket: None,
84 do_spaces_access_key: None,
85 do_spaces_secret_key: None,
86 },
87 auth: AuthConfig {
88 jwt_secret: "dev-secret-change-in-production".to_string(),
89 itchio_client_id: "".to_string(),
90 itchio_oauth_url: "https://itch.io/user/oauth".to_string(),
91 },
92 log_level: "info".to_string(),
93 }
94 }
95}
96
97impl std::fmt::Display for AppConfig {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(
100 f,
101 "{}:{} (db: {}, storage: {})",
102 self.server.host, self.server.port, self.database.path, self.storage.provider
103 )
104 }
105}