lib.rs

  1pub mod api;
  2pub mod auth;
  3pub mod db;
  4pub mod env;
  5pub mod executor;
  6pub mod rpc;
  7
  8#[cfg(test)]
  9mod tests;
 10
 11use axum::{http::StatusCode, response::IntoResponse};
 12use db::Database;
 13use executor::Executor;
 14use serde::Deserialize;
 15use std::{path::PathBuf, sync::Arc};
 16
 17pub type Result<T, E = Error> = std::result::Result<T, E>;
 18
 19pub enum Error {
 20    Http(StatusCode, String),
 21    Database(sea_orm::error::DbErr),
 22    Internal(anyhow::Error),
 23}
 24
 25impl From<anyhow::Error> for Error {
 26    fn from(error: anyhow::Error) -> Self {
 27        Self::Internal(error)
 28    }
 29}
 30
 31impl From<sea_orm::error::DbErr> for Error {
 32    fn from(error: sea_orm::error::DbErr) -> Self {
 33        Self::Database(error)
 34    }
 35}
 36
 37impl From<axum::Error> for Error {
 38    fn from(error: axum::Error) -> Self {
 39        Self::Internal(error.into())
 40    }
 41}
 42
 43impl From<hyper::Error> for Error {
 44    fn from(error: hyper::Error) -> Self {
 45        Self::Internal(error.into())
 46    }
 47}
 48
 49impl From<serde_json::Error> for Error {
 50    fn from(error: serde_json::Error) -> Self {
 51        Self::Internal(error.into())
 52    }
 53}
 54
 55impl IntoResponse for Error {
 56    fn into_response(self) -> axum::response::Response {
 57        match self {
 58            Error::Http(code, message) => (code, message).into_response(),
 59            Error::Database(error) => {
 60                (StatusCode::INTERNAL_SERVER_ERROR, format!("{}", &error)).into_response()
 61            }
 62            Error::Internal(error) => {
 63                (StatusCode::INTERNAL_SERVER_ERROR, format!("{}", &error)).into_response()
 64            }
 65        }
 66    }
 67}
 68
 69impl std::fmt::Debug for Error {
 70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 71        match self {
 72            Error::Http(code, message) => (code, message).fmt(f),
 73            Error::Database(error) => error.fmt(f),
 74            Error::Internal(error) => error.fmt(f),
 75        }
 76    }
 77}
 78
 79impl std::fmt::Display for Error {
 80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 81        match self {
 82            Error::Http(code, message) => write!(f, "{code}: {message}"),
 83            Error::Database(error) => error.fmt(f),
 84            Error::Internal(error) => error.fmt(f),
 85        }
 86    }
 87}
 88
 89impl std::error::Error for Error {}
 90
 91#[derive(Default, Deserialize)]
 92pub struct Config {
 93    pub http_port: u16,
 94    pub database_url: String,
 95    pub database_max_connections: u32,
 96    pub api_token: String,
 97    pub invite_link_prefix: String,
 98    pub live_kit_server: Option<String>,
 99    pub live_kit_key: Option<String>,
100    pub live_kit_secret: Option<String>,
101    pub rust_log: Option<String>,
102    pub log_json: Option<bool>,
103    pub zed_environment: String,
104}
105
106#[derive(Default, Deserialize)]
107pub struct MigrateConfig {
108    pub database_url: String,
109    pub migrations_path: Option<PathBuf>,
110}
111
112pub struct AppState {
113    pub db: Arc<Database>,
114    pub live_kit_client: Option<Arc<dyn live_kit_server::api::Client>>,
115    pub config: Config,
116}
117
118impl AppState {
119    pub async fn new(config: Config) -> Result<Arc<Self>> {
120        let mut db_options = db::ConnectOptions::new(config.database_url.clone());
121        db_options.max_connections(config.database_max_connections);
122        let mut db = Database::new(db_options, Executor::Production).await?;
123        db.initialize_notification_kinds().await?;
124
125        let live_kit_client = if let Some(((server, key), secret)) = config
126            .live_kit_server
127            .as_ref()
128            .zip(config.live_kit_key.as_ref())
129            .zip(config.live_kit_secret.as_ref())
130        {
131            Some(Arc::new(live_kit_server::api::LiveKitClient::new(
132                server.clone(),
133                key.clone(),
134                secret.clone(),
135            )) as Arc<dyn live_kit_server::api::Client>)
136        } else {
137            None
138        };
139
140        let this = Self {
141            db: Arc::new(db),
142            live_kit_client,
143            config,
144        };
145        Ok(Arc::new(this))
146    }
147}