82 lines
1.9 KiB
Rust
82 lines
1.9 KiB
Rust
use std::sync::{Arc, Mutex};
|
|
|
|
use cron_tab::Cron;
|
|
use gpio_cdev::Chip;
|
|
use sea_orm::Database;
|
|
use tokio::net::TcpListener;
|
|
use utoipa::OpenApi;
|
|
use utoipa_axum::router::OpenApiRouter;
|
|
use utoipa_scalar::{Scalar, Servable};
|
|
|
|
use crate::{ringer::{BeepRinger, Ringer, SilentRinger}, scheduler::Scheduler};
|
|
|
|
mod scheduler;
|
|
mod ringer;
|
|
mod types;
|
|
mod resources;
|
|
mod dao;
|
|
mod model;
|
|
|
|
|
|
#[derive(Clone)]
|
|
struct AppState {
|
|
scheduler: Arc<Scheduler>
|
|
}
|
|
|
|
fn construct_ringer() -> Arc<Mutex<dyn Ringer>> {
|
|
let result = Chip::new("/dev/gpiochip0");
|
|
|
|
match result {
|
|
Ok(chip) => {
|
|
let chip = Arc::new(Mutex::new(chip));
|
|
Arc::new(Mutex::new(BeepRinger::new(chip))) as Arc<Mutex<dyn Ringer>>
|
|
},
|
|
Err(e) => {
|
|
println!("Error opening chip (falling back to silent ringer): {}", e);
|
|
Arc::new(Mutex::new(SilentRinger::new())) as Arc<Mutex<dyn Ringer>>
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn app_state() -> AppState {
|
|
let cron = Arc::new(Mutex::new(Cron::new(chrono::Local)));
|
|
let db = Database::connect("sqlite://snooze-pal.db").await.unwrap();
|
|
let ringer = construct_ringer();
|
|
|
|
AppState {
|
|
scheduler: Arc::new(Scheduler::new(
|
|
ringer,
|
|
cron.clone(),
|
|
Arc::new(db)
|
|
))
|
|
}
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let app_state = app_state().await;
|
|
app_state.scheduler.start().await;
|
|
start_axum_server(app_state).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(OpenApi)]
|
|
struct ApiDocs;
|
|
|
|
async fn start_axum_server(app_state: AppState) {
|
|
let docs = ApiDocs::openapi();
|
|
|
|
let (router, spec) = OpenApiRouter::<AppState>::with_openapi(docs)
|
|
.nest("/v1", resources::router())
|
|
.with_state(app_state)
|
|
.split_for_parts();
|
|
|
|
let router = router.merge(Scalar::with_url("/docs", spec));
|
|
let listener = TcpListener::bind("0.0.0.0:8080")
|
|
.await.expect("Failed to bind to port 8080. It may be taken by another process.");
|
|
|
|
axum::serve(listener, router)
|
|
.await.expect("Failed to serve");
|
|
}
|