diff --git a/Cargo.toml b/Cargo.toml index 23291f9..ad67944 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,4 @@ dotenvy = "0.15.7" compile-time-run = "0.2.12" actix-web = "4.5.1" -sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-native-tls"] } +sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-native-tls", "mysql"] } diff --git a/src/api/endpoints.rs b/src/api/endpoints.rs new file mode 100644 index 0000000..08bcdd3 --- /dev/null +++ b/src/api/endpoints.rs @@ -0,0 +1,6 @@ +use actix_web::{post, HttpResponse, Responder}; + +#[post("/account/register")] +pub async fn account_register() -> impl Responder { + HttpResponse::Ok() +} diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..2ef5a46 --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,25 @@ +use crate::backend::Backend; +use crate::config::Config; +use actix_web::{web, App, HttpServer}; +use anyhow::Result; +use log::info; + +mod endpoints; + +pub async fn start(config: &Config, backend: Backend) -> Result<()> { + let server = HttpServer::new(move || { + App::new() + .app_data(web::Data::new(backend.clone())) + .service(endpoints::account_register) + }) + .bind((config.addr.as_str(), config.port))?; + + if let Some(threads) = config.threads { + server.workers(threads as usize).run().await?; + } else { + server.run().await?; + } + info!("API online"); + + Ok(()) +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs new file mode 100644 index 0000000..2331049 --- /dev/null +++ b/src/backend/mod.rs @@ -0,0 +1,35 @@ +use crate::config::Config; +use anyhow::Result; +use log::info; +use sqlx::MySqlPool; + +#[derive(Debug, Clone)] +pub struct Backend { + pool: MySqlPool, +} + +pub async fn start(config: &Config) -> Result { + let pool = MySqlPool::connect(config.database.as_str()).await?.into(); + + sqlx::query!( + r#"CREATE TABLE IF NOT EXISTS Users ( + username VARCHAR(32) NOT NULL PRIMARY KEY, + password VARCHAR(98) NOT NULL + );"# + ) + .execute(&pool) + .await?; + + sqlx::query!( + r#"CREATE TABLE IF NOT EXISTS Relays ( + id BINARY(16) NOT NULL PRIMARY KEY, + secret VARCHAR(98) NOT NULL + );"# + ) + .execute(&pool) + .await?; + + info!("Backend initialized"); + + Ok(Backend { pool }) +} diff --git a/src/config.rs b/src/config.rs index 6dd1677..4847c0c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,9 +4,10 @@ use std::env; #[derive(Debug)] pub struct Config { - addr: String, - port: u16, - database: String, + pub addr: String, + pub port: u16, + pub database: String, + pub threads: Option, } impl Config { @@ -27,7 +28,14 @@ impl Config { database: match env::var("CR_DATABASE") { Ok(db) => db, Err(_) => bail!("The environment variable CR_DATABASE is required!"), - } + }, + threads: match env::var("CR_THREADS") { + Ok(str) => match str.parse() { + Ok(threads) => Some(threads), + Err(_) => bail!("Failed to parse environment variable CR_THREAD: '{str}' is not a valid number!"), + }, + Err(_) => None + }, }) } } diff --git a/src/main.rs b/src/main.rs index da31568..ec737b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +mod api; +mod backend; mod config; use anyhow::Result; @@ -21,5 +23,8 @@ async fn main() -> Result<()> { println!("{config:#?}"); + let backend = backend::start(&config).await?; + api::start(&config, backend).await?; + Ok(()) }