8
crates/config/Cargo.toml
Normal file
8
crates/config/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "config"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
thiserror.workspace = true
|
||||
serde.workspace = true
|
||||
12
crates/config/src/app_config.rs
Normal file
12
crates/config/src/app_config.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use super::{AuthConfig, EntryConfig, PresetConfig, PushConfig, ServerConfig, StorageConfig};
|
||||
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct AppConfig {
|
||||
pub server: ServerConfig,
|
||||
pub entry: EntryConfig,
|
||||
pub storage: StorageConfig,
|
||||
pub auth: AuthConfig,
|
||||
pub push: PushConfig,
|
||||
pub preset: PresetConfig,
|
||||
}
|
||||
22
crates/config/src/auth_config.rs
Normal file
22
crates/config/src/auth_config.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
const DEFAULT_ACCESS_TOKEN_TTL_SECONDS: u64 = 900;
|
||||
const DEFAULT_REFRESH_TOKEN_TTL_SECONDS: u64 = 2_592_000;
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct AuthConfig {
|
||||
pub jwt_secret: Option<String>,
|
||||
pub access_token_ttl_seconds: u64,
|
||||
pub refresh_token_ttl_seconds: u64,
|
||||
pub allow_registration: bool,
|
||||
}
|
||||
|
||||
impl Default for AuthConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
jwt_secret: None,
|
||||
access_token_ttl_seconds: DEFAULT_ACCESS_TOKEN_TTL_SECONDS,
|
||||
refresh_token_ttl_seconds: DEFAULT_REFRESH_TOKEN_TTL_SECONDS,
|
||||
allow_registration: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
24
crates/config/src/entry_config.rs
Normal file
24
crates/config/src/entry_config.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
const DEFAULT_MAX_CONTENT_LENGTH: usize = 65_536;
|
||||
const DEFAULT_MAX_PHOTOS: usize = 10;
|
||||
const DEFAULT_MAX_VOICE_MEMOS: usize = 5;
|
||||
const DEFAULT_MAX_ACTIVITIES_PER_ENTRY: usize = 50;
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct EntryConfig {
|
||||
pub max_content_length: usize,
|
||||
pub max_photos: usize,
|
||||
pub max_voice_memos: usize,
|
||||
pub max_activities_per_entry: usize,
|
||||
}
|
||||
|
||||
impl Default for EntryConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
max_content_length: DEFAULT_MAX_CONTENT_LENGTH,
|
||||
max_photos: DEFAULT_MAX_PHOTOS,
|
||||
max_voice_memos: DEFAULT_MAX_VOICE_MEMOS,
|
||||
max_activities_per_entry: DEFAULT_MAX_ACTIVITIES_PER_ENTRY,
|
||||
}
|
||||
}
|
||||
}
|
||||
15
crates/config/src/lib.rs
Normal file
15
crates/config/src/lib.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
mod app_config;
|
||||
mod auth_config;
|
||||
mod entry_config;
|
||||
mod preset;
|
||||
mod push_config;
|
||||
mod server_config;
|
||||
mod storage_config;
|
||||
|
||||
pub use app_config::AppConfig;
|
||||
pub use auth_config::AuthConfig;
|
||||
pub use entry_config::EntryConfig;
|
||||
pub use preset::{PresetActivity, PresetConfig};
|
||||
pub use push_config::PushConfig;
|
||||
pub use server_config::{CorsConfig, ServerConfig};
|
||||
pub use storage_config::{MediaBackend, StorageConfig};
|
||||
48
crates/config/src/preset.rs
Normal file
48
crates/config/src/preset.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
pub struct PresetActivity {
|
||||
pub name: String,
|
||||
pub category: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct PresetConfig {
|
||||
pub activities: Vec<PresetActivity>,
|
||||
}
|
||||
|
||||
impl Default for PresetConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
activities: default_activities(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_activities() -> Vec<PresetActivity> {
|
||||
let groups: &[(&str, &[&str])] = &[
|
||||
("social", &["family", "friends", "date", "party"]),
|
||||
(
|
||||
"hobbies",
|
||||
&["movies & tv", "reading", "gaming", "sport", "relax"],
|
||||
),
|
||||
(
|
||||
"sleep",
|
||||
&["sleep early", "good sleep", "medium sleep", "bad sleep"],
|
||||
),
|
||||
(
|
||||
"health",
|
||||
&["exercise", "eat healthy", "drink water", "walk"],
|
||||
),
|
||||
("chores", &["shopping", "cleaning", "cooking", "laundry"]),
|
||||
];
|
||||
|
||||
groups
|
||||
.iter()
|
||||
.flat_map(|(category, names)| {
|
||||
names.iter().map(move |name| PresetActivity {
|
||||
name: (*name).into(),
|
||||
category: Some((*category).into()),
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
7
crates/config/src/push_config.rs
Normal file
7
crates/config/src/push_config.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct PushConfig {
|
||||
pub enabled: bool,
|
||||
pub vapid_private_key: Option<String>,
|
||||
pub vapid_subject: Option<String>,
|
||||
}
|
||||
42
crates/config/src/server_config.rs
Normal file
42
crates/config/src/server_config.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
const DEFAULT_HOST: &str = "0.0.0.0";
|
||||
const DEFAULT_PORT: u16 = 3000;
|
||||
const DEFAULT_MAX_BODY_SIZE: usize = 10 * 1024 * 1024;
|
||||
const DEFAULT_SPA_DIR: &str = "spa/dist";
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct ServerConfig {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub max_body_size: usize,
|
||||
pub spa_dir: String,
|
||||
pub cors: CorsConfig,
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
host: DEFAULT_HOST.into(),
|
||||
port: DEFAULT_PORT,
|
||||
max_body_size: DEFAULT_MAX_BODY_SIZE,
|
||||
spa_dir: DEFAULT_SPA_DIR.into(),
|
||||
cors: CorsConfig::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct CorsConfig {
|
||||
pub allowed_origins: Vec<String>,
|
||||
pub allow_any_origin: bool,
|
||||
}
|
||||
|
||||
impl Default for CorsConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
allowed_origins: Vec::new(),
|
||||
allow_any_origin: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
43
crates/config/src/storage_config.rs
Normal file
43
crates/config/src/storage_config.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
const DEFAULT_DATA_DIR: &str = "./data";
|
||||
const DEFAULT_MEDIA_DIR: &str = "media";
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(tag = "backend")]
|
||||
pub enum MediaBackend {
|
||||
#[serde(rename = "local")]
|
||||
Local { media_dir: String },
|
||||
#[serde(rename = "s3")]
|
||||
S3 {
|
||||
bucket: String,
|
||||
region: String,
|
||||
endpoint: Option<String>,
|
||||
access_key: Option<String>,
|
||||
secret_key: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Default for MediaBackend {
|
||||
fn default() -> Self {
|
||||
Self::Local {
|
||||
media_dir: DEFAULT_MEDIA_DIR.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct StorageConfig {
|
||||
pub data_dir: String,
|
||||
pub database_url: Option<String>,
|
||||
pub media: MediaBackend,
|
||||
}
|
||||
|
||||
impl Default for StorageConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
data_dir: DEFAULT_DATA_DIR.into(),
|
||||
database_url: None,
|
||||
media: MediaBackend::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user