From 9621cd5d4e6923d4fd326a3bf31ffa1bd457a196 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Mon, 24 Nov 2025 22:10:46 +0200 Subject: [PATCH] feat: separate routes to module --- src/main.rs | 60 ++++------------------------------------ src/routes/message.rs | 64 +++++++++++++++++++++++++++++++++++++++++++ src/routes/mod.rs | 8 ++++++ src/service/email.rs | 2 +- src/service/gotify.rs | 2 +- src/service/matrix.rs | 2 +- src/service/mod.rs | 2 +- 7 files changed, 81 insertions(+), 59 deletions(-) create mode 100644 src/routes/message.rs create mode 100644 src/routes/mod.rs diff --git a/src/main.rs b/src/main.rs index a8ac40c..53a98cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,17 +8,15 @@ use std::sync::Arc; use axum::{ - Json, Router, - http::HeaderMap, - response::{Html, IntoResponse}, + Router, + response::Html, routing::{get, post}, }; use clap::Parser; use reqwest::StatusCode; -use serde::Deserialize; use tokio::net::TcpListener; use tower_http::trace::TraceLayer; -use tracing::{error, info}; +use tracing::info; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod config; @@ -26,6 +24,7 @@ use config::Config; mod state; use state::State; +mod routes; mod service; const LICENSE_HTML: &str = include_str!("../static/license.html"); @@ -74,7 +73,7 @@ async fn main() { "/message", post({ let shared_state = Arc::clone(&state); - move |headers, body| message(shared_state, headers, body) + move |headers, body| routes::message::message(shared_state, headers, body) }), ) .layer(TraceLayer::new_for_http()) @@ -85,52 +84,3 @@ async fn main() { let listener = TcpListener::bind(addr).await.unwrap(); axum::serve(listener, router).await.unwrap(); } - -#[derive(Deserialize)] -struct MessageForm { - title: String, - message: String, - #[serde(default)] - format_commonmark: bool, -} - -async fn message( - state: Arc, - headers: HeaderMap, - Json(message): Json, -) -> impl IntoResponse { - let token = match headers.get("Authorization") { - Some(token) => match token.to_str() { - Ok(token) => token, - Err(_) => { - return (StatusCode::UNAUTHORIZED, "unauthorized"); - } - }, - None => { - return (StatusCode::UNAUTHORIZED, "unauthorized"); - } - }; - - let notifier = match state.notifiers.iter().find(|(_k, v)| v.token == token) { - Some(n) => n, - None => return (StatusCode::UNAUTHORIZED, "unauthorized"), - }; - - info!(msg = "message", notifier = notifier.0); - - for (_k, v) in state - .services - .iter() - .filter(|(k, _v)| notifier.1.services.contains(k)) - { - match v.send(&message).await { - Ok(_) => {} - Err(err) => { - error!(msg = "message sending failed", ?err); - return (StatusCode::INTERNAL_SERVER_ERROR, "failed to send message"); - } - } - } - - (StatusCode::OK, "") -} diff --git a/src/routes/message.rs b/src/routes/message.rs new file mode 100644 index 0000000..fd3c96d --- /dev/null +++ b/src/routes/message.rs @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2025 Jonni Liljamo + * + * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for + * more information. + */ + +use std::sync::Arc; + +use axum::{Json, http::HeaderMap, response::IntoResponse}; +use reqwest::StatusCode; +use serde::Deserialize; +use tracing::{error, info}; + +use crate::state::State; + +#[derive(Deserialize)] +pub struct MessageForm { + pub title: String, + pub message: String, + #[serde(default)] + pub format_commonmark: bool, +} + +pub async fn message( + state: Arc, + headers: HeaderMap, + Json(message): Json, +) -> impl IntoResponse { + let token = match headers.get("Authorization") { + Some(token) => match token.to_str() { + Ok(token) => token, + Err(_) => { + return (StatusCode::UNAUTHORIZED, "unauthorized"); + } + }, + None => { + return (StatusCode::UNAUTHORIZED, "unauthorized"); + } + }; + + let notifier = match state.notifiers.iter().find(|(_k, v)| v.token == token) { + Some(n) => n, + None => return (StatusCode::UNAUTHORIZED, "unauthorized"), + }; + + info!(msg = "message", notifier = notifier.0); + + for (_k, v) in state + .services + .iter() + .filter(|(k, _v)| notifier.1.services.contains(k)) + { + match v.send(&message).await { + Ok(_) => {} + Err(err) => { + error!(msg = "message sending failed", ?err); + return (StatusCode::INTERNAL_SERVER_ERROR, "failed to send message"); + } + } + } + + (StatusCode::OK, "") +} diff --git a/src/routes/mod.rs b/src/routes/mod.rs new file mode 100644 index 0000000..42f212d --- /dev/null +++ b/src/routes/mod.rs @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2025 Jonni Liljamo + * + * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for + * more information. + */ + +pub mod message; diff --git a/src/service/email.rs b/src/service/email.rs index a79b968..d754a9a 100644 --- a/src/service/email.rs +++ b/src/service/email.rs @@ -14,8 +14,8 @@ use lettre::{ use serde::{Deserialize, Serialize}; use crate::{ - MessageForm, config::{ServiceConfig, deserialize_token}, + routes::message::MessageForm, }; use super::Service; diff --git a/src/service/gotify.rs b/src/service/gotify.rs index f3f1d26..b409856 100644 --- a/src/service/gotify.rs +++ b/src/service/gotify.rs @@ -9,8 +9,8 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; use crate::{ - MessageForm, config::{ServiceConfig, deserialize_token}, + routes::message::MessageForm, }; use super::Service; diff --git a/src/service/matrix.rs b/src/service/matrix.rs index 9e737d0..5166923 100644 --- a/src/service/matrix.rs +++ b/src/service/matrix.rs @@ -10,8 +10,8 @@ use serde::{Deserialize, Serialize}; use serde_json::json; use crate::{ - MessageForm, config::{ServiceConfig, deserialize_token}, + routes::message::MessageForm, }; use super::Service; diff --git a/src/service/mod.rs b/src/service/mod.rs index 1f6e0c2..7c9629a 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -8,7 +8,7 @@ use async_trait::async_trait; use pastey::paste; -use crate::{MessageForm, config::ServiceConfig}; +use crate::{config::ServiceConfig, routes::message::MessageForm}; pub mod email; pub mod gotify; -- 2.44.1