switched back to axum wip

This commit is contained in:
2026-03-02 17:03:22 +01:00
parent f7e55536ab
commit 05ba925d54
6 changed files with 240 additions and 68 deletions

179
Cargo.lock generated
View File

@@ -362,6 +362,15 @@ dependencies = [
"apistos-plugins", "apistos-plugins",
] ]
[[package]]
name = "arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
dependencies = [
"derive_arbitrary",
]
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.7.6" version = "0.7.6"
@@ -871,6 +880,17 @@ dependencies = [
"serde_core", "serde_core",
] ]
[[package]]
name = "derive_arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "2.1.1" version = "2.1.1"
@@ -989,6 +1009,7 @@ checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
"zlib-rs",
] ]
[[package]] [[package]]
@@ -1928,6 +1949,12 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]] [[package]]
name = "pem-rfc7468" name = "pem-rfc7468"
version = "0.7.0" version = "0.7.0"
@@ -2323,6 +2350,40 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rust-embed"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.111",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1"
dependencies = [
"sha2",
"walkdir",
]
[[package]] [[package]]
name = "rust_decimal" name = "rust_decimal"
version = "1.40.0" version = "1.40.0"
@@ -2360,6 +2421,15 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@@ -2646,6 +2716,9 @@ dependencies = [
"sea-orm", "sea-orm",
"serde", "serde",
"tokio", "tokio",
"utoipa",
"utoipa-axum",
"utoipa-swagger-ui",
] ]
[[package]] [[package]]
@@ -3312,6 +3385,61 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utoipa"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993"
dependencies = [
"indexmap",
"serde",
"serde_json",
"utoipa-gen",
]
[[package]]
name = "utoipa-axum"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c25bae5bccc842449ec0c5ddc5cbb6a3a1eaeac4503895dc105a1138f8234a0"
dependencies = [
"axum",
"paste",
"tower-layer",
"tower-service",
"utoipa",
]
[[package]]
name = "utoipa-gen"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b"
dependencies = [
"proc-macro2",
"quote",
"regex",
"syn 2.0.111",
]
[[package]]
name = "utoipa-swagger-ui"
version = "9.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55"
dependencies = [
"axum",
"base64",
"mime_guess",
"regex",
"rust-embed",
"serde",
"serde_json",
"url",
"utoipa",
"zip",
]
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.20.0" version = "1.20.0"
@@ -3335,6 +3463,16 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.1+wasi-snapshot-preview1" version = "0.11.1+wasi-snapshot-preview1"
@@ -3411,6 +3549,15 @@ dependencies = [
"wasite", "wasite",
] ]
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.62.2" version = "0.62.2"
@@ -3840,12 +3987,44 @@ dependencies = [
"syn 2.0.111", "syn 2.0.111",
] ]
[[package]]
name = "zip"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308"
dependencies = [
"arbitrary",
"crc32fast",
"flate2",
"indexmap",
"memchr",
"zopfli",
]
[[package]]
name = "zlib-rs"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3"
[[package]] [[package]]
name = "zmij" name = "zmij"
version = "1.0.3" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9747e91771f56fd7893e1164abd78febd14a670ceec257caad15e051de35f06" checksum = "e9747e91771f56fd7893e1164abd78febd14a670ceec257caad15e051de35f06"
[[package]]
name = "zopfli"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
dependencies = [
"bumpalo",
"crc32fast",
"log",
"simd-adler32",
]
[[package]] [[package]]
name = "zstd" name = "zstd"
version = "0.13.3" version = "0.13.3"

View File

@@ -14,4 +14,11 @@ actix-web = "4.12.1"
paperclip = { version = "0.9.5", features = ["actix4"] } paperclip = { version = "0.9.5", features = ["actix4"] }
apistos = { version = "0.6.0", features = ["swagger-ui"] } apistos = { version = "0.6.0", features = ["swagger-ui"] }
schemars = { package = "apistos-schemars", version = "0.8" } schemars = { package = "apistos-schemars", version = "0.8" }
sea-orm = { version = "1.1.19", features = ["macros", "runtime-tokio", "sqlx-sqlite"] } sea-orm = { version = "1.1.19", features = [
"macros",
"runtime-tokio",
"sqlx-sqlite",
] }
utoipa = { version = "5.4.0", features = ["axum_extras", "chrono"] }
utoipa-axum = "0.2.0"
utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] }

View File

@@ -1,10 +1,14 @@
use std::sync::{Arc, Mutex}; 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 apistos::{SwaggerUIConfig, app::{BuildConfig, OpenApiWrapper}, info::Info, spec::Spec};
use cron_tab::Cron; use cron_tab::Cron;
use gpio_cdev::Chip; use gpio_cdev::Chip;
use sea_orm::Database; 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}; use crate::{ringer::BeepRinger, scheduler::Scheduler};
@@ -36,34 +40,29 @@ async fn app_state() -> AppState {
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { 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(()) Ok(())
} }
#[derive(OpenApi)]
struct ApiDocs;
async fn start_actix_server(app_state: AppState) -> std::io::Result<()> { async fn start_axum_server() {
let _ = HttpServer::new(move || { let docs = ApiDocs::openapi();
let spec = Spec {
info: Info {
title: "Snooze Pal".to_string(),
version: "0.0.1".to_string(),
..Default::default()
},
..Default::default()
};
App::new() let (router, spec) = OpenApiRouter::with_openapi(docs)
.document(spec) .nest("/v1", resources::router())
.service(resources::v1()) .split_for_parts();
.app_data(web::Data::new(app_state.clone()))
.build_with("/openapi.json", BuildConfig::default().with(SwaggerUIConfig::new(&"/swagger")))
}).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");
} }

View File

@@ -1,7 +1,7 @@
mod post; mod post;
use apistos::web; use utoipa_axum::{router::OpenApiRouter, routes};
pub fn resource() -> web::Resource { pub fn router() -> OpenApiRouter {
web::resource("/alarm") OpenApiRouter::new()
.route(web::post().to(post::post)) .routes(routes!(post::post_handler))
} }

View File

@@ -1,56 +1,40 @@
use std::{fmt::Display}; use axum::Json;
use axum::http::StatusCode;
use actix_web::{ResponseError, web::{Data, Json}}; use axum::debug_handler;
use apistos::{ApiComponent, ApiErrorComponent, actix::CreatedJson}; use axum::response::IntoResponse;
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Serialize, Deserialize}; use serde::Deserialize;
use utoipa::{IntoResponses, ToSchema};
use crate::AppState; #[derive(Debug, Deserialize, JsonSchema, ToSchema)]
#[derive(Debug, Deserialize, JsonSchema, ApiComponent)]
pub struct RequestBody { pub struct RequestBody {
time: DateTime<Local>, time: DateTime<Local>,
} }
#[derive(Debug, Serialize, JsonSchema, ApiComponent)] #[derive(IntoResponses)]
pub struct SuccessResponse { pub enum Responses {
pub time: DateTime<Local>, #[response(status = 200)]
pub enabled: bool Ok
} }
#[derive(Debug, Deserialize, Serialize, ApiErrorComponent)] impl IntoResponse for Responses {
#[openapi_error(status(code = 500, description = "The alarm could not be created"))] fn into_response(self) -> axum::response::Response {
pub enum ErrorResponse {
InternalError(String)
}
impl Display for ErrorResponse {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { 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( #[utoipa::path(
summary = "Add new alarm", post,
description = r###"Creates new Alarm"###, path = "",
error_code= 500, responses(
Responses
)
)] )]
pub async fn post(data: Data<AppState>, body: Json<RequestBody>) -> Result<CreatedJson<SuccessResponse>, ErrorResponse> { #[debug_handler]
let result = data.scheduler.add_alarm(body.time); pub async fn post_handler(Json(body): Json<RequestBody>) -> Responses {
todo!()
match result {
Ok(alarm) => Ok(CreatedJson(SuccessResponse { time: alarm.time, enabled: alarm.enabled })),
Err(e) => Err(ErrorResponse::InternalError(e)),
}
} }

View File

@@ -1,5 +1,8 @@
use utoipa_axum::router::OpenApiRouter;
mod alarm; mod alarm;
pub fn v1() -> apistos::web::Scope { pub fn router() -> OpenApiRouter {
apistos::web::scope("/v1").service(alarm::resource()) OpenApiRouter::new()
.nest("/alarm", alarm::router())
} }