Skip to content
Clone
194c44c
409 lines 10.6 KB Rust
use serde::Deserialize;
use serde::de::DeserializeOwned;
use crate::agents::AgentsConfig;
use crate::ai::AiConfig;
use crate::aihost::AiHostServerConfig;
use crate::apihost::ApihostConfig as ApihostSection;
use crate::auth::AuthConfig;
use crate::chat::ChatConfig;
use crate::ci::CiConfig;
use crate::database::DatabaseConfig;
use crate::email::EmailConfig;
use crate::email_queue::EmailQueueConfig;
use crate::error::ConfigError;
use crate::git::GitConfig;
use crate::githost::GithostConfig as GithostSection;
use crate::health::HealthConfig;
use crate::im::ImServerConfig;
use crate::import::ImportConfig;
use crate::issues::IssueConfig;
use crate::livekit::LiveKitConfig;
use crate::mcp::McpConfig;
use crate::pow::PowConfig;
use crate::push::PushConfig;
use crate::quota::QuotaConfig;
use crate::redis::RedisConfig;
use crate::s3::S3Config;
use crate::sandbox_rpc::SandboxRpcConfig;
use crate::search::SearchConfig;
use crate::space::SpaceConfig;
use crate::user::UserConfig;
use crate::web::WebConfig;
use crate::webhook::WebhookConfig;
use crate::{AppConfig, loader};
pub trait ScopedConfig: DeserializeOwned + Sized {
fn validate_scoped(&self) -> Result<(), String>;
fn load() -> Result<Self, ConfigError> {
let cfg: Self = loader::figment().extract().map_err(ConfigError::from)?;
cfg.validate_scoped().map_err(ConfigError::Validation)?;
Ok(cfg)
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct MigrateConfig {
pub database: DatabaseConfig,
}
impl ScopedConfig for MigrateConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct MailsConfig {
pub redis: RedisConfig,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub health: HealthConfig,
}
impl ScopedConfig for MailsConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.redis.validate()?;
self.email.is_valid()?;
self.email_queue.is_valid()?;
self.health.is_valid()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct WebhookServiceConfig {
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub s3: S3Config,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub web: WebConfig,
pub git: GitConfig,
pub ci: CiConfig,
pub webhook: WebhookConfig,
pub health: HealthConfig,
}
impl WebhookServiceConfig {
pub fn into_app_config(self) -> AppConfig {
AppConfig {
database: self.database,
redis: self.redis,
s3: self.s3,
email: self.email,
email_queue: self.email_queue,
web: self.web,
git: self.git,
ci: self.ci,
webhook: self.webhook,
health: self.health,
..Default::default()
}
}
}
impl ScopedConfig for WebhookServiceConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()?;
self.redis.validate()?;
self.email.is_valid()?;
self.email_queue.is_valid()?;
self.ci.validate()?;
self.webhook.is_valid()?;
self.health.is_valid()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct SynchostConfig {
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub git: GitConfig,
pub health: HealthConfig,
pub search: SearchConfig,
pub import: ImportConfig,
}
impl ScopedConfig for SynchostConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()?;
self.redis.validate()?;
self.search.validate()?;
self.import.validate()?;
self.health.is_valid()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct GithostConfig {
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub s3: S3Config,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub web: WebConfig,
pub git: GitConfig,
pub githost: GithostSection,
pub ci: CiConfig,
pub ai: AiConfig,
}
impl GithostConfig {
pub fn into_app_config(self) -> AppConfig {
AppConfig {
database: self.database,
redis: self.redis,
s3: self.s3,
email: self.email,
email_queue: self.email_queue,
web: self.web,
git: self.git,
githost: self.githost,
ci: self.ci,
ai: self.ai,
..Default::default()
}
}
}
impl ScopedConfig for GithostConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()?;
self.redis.validate()?;
self.email.is_valid()?;
self.email_queue.is_valid()?;
self.githost.is_valid()?;
self.ai.validate()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct ApihostConfig {
pub ci: CiConfig,
pub webhook: WebhookConfig,
pub s3: S3Config,
pub redis: RedisConfig,
pub chat: ChatConfig,
pub database: DatabaseConfig,
pub pow: PowConfig,
pub auth: AuthConfig,
pub web: WebConfig,
pub user: UserConfig,
pub quota: QuotaConfig,
pub space: SpaceConfig,
pub issues: IssueConfig,
pub agents: AgentsConfig,
pub sandbox_rpc: SandboxRpcConfig,
pub mcp: McpConfig,
pub git: GitConfig,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub apihost: ApihostSection,
pub search: SearchConfig,
pub import: ImportConfig,
pub ai: AiConfig,
pub livekit: LiveKitConfig,
pub push: PushConfig,
}
impl ApihostConfig {
pub fn into_app_config(self) -> AppConfig {
AppConfig {
ci: self.ci,
webhook: self.webhook,
s3: self.s3,
redis: self.redis,
chat: self.chat,
database: self.database,
pow: self.pow,
auth: self.auth,
web: self.web,
user: self.user,
quota: self.quota,
space: self.space,
issues: self.issues,
agents: self.agents,
sandbox_rpc: self.sandbox_rpc,
mcp: self.mcp,
git: self.git,
email: self.email,
email_queue: self.email_queue,
apihost: self.apihost,
search: self.search,
import: self.import,
ai: self.ai,
livekit: self.livekit,
push: self.push,
..Default::default()
}
}
}
impl ScopedConfig for ApihostConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.ci.validate()?;
self.redis.validate()?;
self.database.validate()?;
self.pow.validate()?;
self.auth.validate()?;
self.chat.is_valid()?;
self.mcp.is_valid()?;
self.email.is_valid()?;
self.email_queue.is_valid()?;
self.search.validate()?;
self.import.validate()?;
self.apihost.is_valid()?;
self.ai.validate()?;
self.livekit.is_valid()?;
self.agents.validate()?;
self.sandbox_rpc.is_valid()?;
self.push.is_valid()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct ImConfig {
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub s3: S3Config,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub chat: ChatConfig,
pub web: WebConfig,
pub auth: AuthConfig,
pub im: ImServerConfig,
}
impl ImConfig {
pub fn into_app_config(self) -> AppConfig {
AppConfig {
database: self.database,
redis: self.redis,
s3: self.s3,
email: self.email,
email_queue: self.email_queue,
chat: self.chat,
web: self.web,
auth: self.auth,
im: self.im,
..Default::default()
}
}
}
impl ScopedConfig for ImConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()?;
self.redis.validate()?;
self.auth.validate()?;
self.chat.is_valid()?;
self.email.is_valid()?;
self.email_queue.is_valid()?;
self.im.is_valid()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct AiHostConfig {
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub git: GitConfig,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub s3: S3Config,
pub ai: AiConfig,
pub aihost: AiHostServerConfig,
pub health: HealthConfig,
}
impl AiHostConfig {
pub fn into_app_config(self) -> AppConfig {
AppConfig {
database: self.database,
redis: self.redis,
git: self.git,
email: self.email,
email_queue: self.email_queue,
s3: self.s3,
ai: self.ai,
aihost: self.aihost,
health: self.health,
..Default::default()
}
}
}
impl ScopedConfig for AiHostConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()?;
self.redis.validate()?;
self.ai.validate()?;
self.aihost.is_valid()?;
self.health.is_valid()
}
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
pub struct McpHostConfig {
pub database: DatabaseConfig,
pub redis: RedisConfig,
pub s3: S3Config,
pub email: EmailConfig,
pub email_queue: EmailQueueConfig,
pub push: PushConfig,
pub auth: AuthConfig,
pub user: UserConfig,
pub quota: QuotaConfig,
pub space: SpaceConfig,
pub issues: IssueConfig,
pub git: GitConfig,
pub web: WebConfig,
pub ai: AiConfig,
pub mcp: McpConfig,
}
impl McpHostConfig {
pub fn into_app_config(self) -> AppConfig {
AppConfig {
database: self.database,
redis: self.redis,
s3: self.s3,
email: self.email,
email_queue: self.email_queue,
push: self.push,
auth: self.auth,
user: self.user,
quota: self.quota,
space: self.space,
issues: self.issues,
git: self.git,
web: self.web,
ai: self.ai,
mcp: self.mcp,
..Default::default()
}
}
}
impl ScopedConfig for McpHostConfig {
fn validate_scoped(&self) -> Result<(), String> {
self.database.validate()?;
self.redis.validate()?;
self.auth.validate()?;
self.email.is_valid()?;
self.email_queue.is_valid()?;
self.ai.validate()?;
self.mcp.is_valid()?;
self.push.is_valid()
}
}