switched back to axum wip
This commit is contained in:
41
src/main.rs
41
src/main.rs
@@ -1,10 +1,14 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use actix_web::{App, HttpServer, web};
|
||||
use actix_web::{App, HttpServer, web::{self, resource}};
|
||||
use apistos::{SwaggerUIConfig, app::{BuildConfig, OpenApiWrapper}, info::Info, spec::Spec};
|
||||
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_swagger_ui::SwaggerUi;
|
||||
|
||||
use crate::{ringer::BeepRinger, scheduler::Scheduler};
|
||||
|
||||
@@ -36,34 +40,29 @@ async fn app_state() -> AppState {
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let app_state = app_state().await;
|
||||
// let app_state = app_state().await;
|
||||
|
||||
app_state.scheduler.start();
|
||||
// app_state.scheduler.start();
|
||||
|
||||
let _ = start_actix_server(app_state).await;
|
||||
start_axum_server().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(OpenApi)]
|
||||
struct ApiDocs;
|
||||
|
||||
async fn start_actix_server(app_state: AppState) -> std::io::Result<()> {
|
||||
let _ = HttpServer::new(move || {
|
||||
let spec = Spec {
|
||||
info: Info {
|
||||
title: "Snooze Pal".to_string(),
|
||||
version: "0.0.1".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
async fn start_axum_server() {
|
||||
let docs = ApiDocs::openapi();
|
||||
|
||||
App::new()
|
||||
.document(spec)
|
||||
.service(resources::v1())
|
||||
.app_data(web::Data::new(app_state.clone()))
|
||||
.build_with("/openapi.json", BuildConfig::default().with(SwaggerUIConfig::new(&"/swagger")))
|
||||
let (router, spec) = OpenApiRouter::with_openapi(docs)
|
||||
.nest("/v1", resources::router())
|
||||
.split_for_parts();
|
||||
|
||||
}).bind("0.0.0.0:8080")?.run().await;
|
||||
let router = router.merge(SwaggerUi::new("/swagger-ui").url("/openapi.json", 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.");
|
||||
|
||||
Ok(())
|
||||
axum::serve(listener, router)
|
||||
.await.expect("Failed to serve");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod post;
|
||||
use apistos::web;
|
||||
use utoipa_axum::{router::OpenApiRouter, routes};
|
||||
|
||||
pub fn resource() -> web::Resource {
|
||||
web::resource("/alarm")
|
||||
.route(web::post().to(post::post))
|
||||
pub fn router() -> OpenApiRouter {
|
||||
OpenApiRouter::new()
|
||||
.routes(routes!(post::post_handler))
|
||||
}
|
||||
|
||||
@@ -1,56 +1,40 @@
|
||||
use std::{fmt::Display};
|
||||
|
||||
use actix_web::{ResponseError, web::{Data, Json}};
|
||||
use apistos::{ApiComponent, ApiErrorComponent, actix::CreatedJson};
|
||||
use axum::Json;
|
||||
use axum::http::StatusCode;
|
||||
use axum::debug_handler;
|
||||
use axum::response::IntoResponse;
|
||||
use chrono::{DateTime, Local};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::Deserialize;
|
||||
use utoipa::{IntoResponses, ToSchema};
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema, ApiComponent)]
|
||||
#[derive(Debug, Deserialize, JsonSchema, ToSchema)]
|
||||
pub struct RequestBody {
|
||||
time: DateTime<Local>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, JsonSchema, ApiComponent)]
|
||||
pub struct SuccessResponse {
|
||||
pub time: DateTime<Local>,
|
||||
pub enabled: bool
|
||||
#[derive(IntoResponses)]
|
||||
pub enum Responses {
|
||||
#[response(status = 200)]
|
||||
Ok
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, ApiErrorComponent)]
|
||||
#[openapi_error(status(code = 500, description = "The alarm could not be created"))]
|
||||
pub enum ErrorResponse {
|
||||
InternalError(String)
|
||||
}
|
||||
|
||||
impl Display for ErrorResponse {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
impl IntoResponse for Responses {
|
||||
fn into_response(self) -> axum::response::Response {
|
||||
match self {
|
||||
ErrorResponse::InternalError(e) => write!(f, "Internal error: {}", e),
|
||||
Responses::Ok => (StatusCode::OK).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl ResponseError for ErrorResponse {
|
||||
fn status_code(&self) -> actix_web::http::StatusCode {
|
||||
match self {
|
||||
ErrorResponse::InternalError(_) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[apistos::api_operation(
|
||||
summary = "Add new alarm",
|
||||
description = r###"Creates new Alarm"###,
|
||||
error_code= 500,
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "",
|
||||
responses(
|
||||
Responses
|
||||
)
|
||||
)]
|
||||
pub async fn post(data: Data<AppState>, body: Json<RequestBody>) -> Result<CreatedJson<SuccessResponse>, ErrorResponse> {
|
||||
let result = data.scheduler.add_alarm(body.time);
|
||||
|
||||
match result {
|
||||
Ok(alarm) => Ok(CreatedJson(SuccessResponse { time: alarm.time, enabled: alarm.enabled })),
|
||||
Err(e) => Err(ErrorResponse::InternalError(e)),
|
||||
}
|
||||
#[debug_handler]
|
||||
pub async fn post_handler(Json(body): Json<RequestBody>) -> Responses {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use utoipa_axum::router::OpenApiRouter;
|
||||
|
||||
mod alarm;
|
||||
|
||||
pub fn v1() -> apistos::web::Scope {
|
||||
apistos::web::scope("/v1").service(alarm::resource())
|
||||
pub fn router() -> OpenApiRouter {
|
||||
OpenApiRouter::new()
|
||||
.nest("/alarm", alarm::router())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user