summaryrefslogtreecommitdiff
path: root/src/message
diff options
context:
space:
mode:
authorojacobson <ojacobson@noreply.codeberg.org>2025-06-21 04:22:52 +0200
committerojacobson <ojacobson@noreply.codeberg.org>2025-06-21 04:22:52 +0200
commitcd1dc0dab4b46bc5712070812192d5ce34071470 (patch)
treec94f5a42f7e734b81892c1289a1d2b566706ba7c /src/message
parentd84ba5cd09b713fac2f193d5c05af7415ea6742d (diff)
parent4e3d5ccac99b24934c972e088cd7eb02bb95df06 (diff)
Reorganize and consolidate HTTP routes.
HTTP routes are now defined in a single, unified module, pulling them out of the topical modules they were formerly part of. This is intended to improve the navigability of the codebase. Previously, finding the handler corresponding to a specific endpoint required prior familiarity, though in practice you could usually guess from topic area. Now, all routes are defined in one place; if you know the path, you can read down the list to find the handler. Handlers themselves live with the domain they are most appropriately "part of," generally (in this version, universally) in a `handlers` submodule. The handlers themselves have been flattened down; rather than representing a path and a method, they now represent a named operation (which is suspiciously similar to the path in most cases). This means that we no longer have constructs like `crate::ui::routes::ch::channel` - it's now `crate::ui::handlers::channel` instead. ## Disclaimer I Solemnly Swear I Didn't Change Any Handlers. ## Prior art I've inadvertently reinvented Django's `urls.py` convention, and I've opted to lean into that. Merges flatter-routes-reorg into main.
Diffstat (limited to 'src/message')
-rw-r--r--src/message/handlers/delete/mod.rs55
-rw-r--r--src/message/handlers/delete/test.rs (renamed from src/message/routes/message/test.rs)13
-rw-r--r--src/message/handlers/mod.rs3
-rw-r--r--src/message/mod.rs6
-rw-r--r--src/message/routes/message/mod.rs61
-rw-r--r--src/message/routes/mod.rs9
6 files changed, 66 insertions, 81 deletions
diff --git a/src/message/handlers/delete/mod.rs b/src/message/handlers/delete/mod.rs
new file mode 100644
index 0000000..5eac4eb
--- /dev/null
+++ b/src/message/handlers/delete/mod.rs
@@ -0,0 +1,55 @@
+use axum::{
+ extract::{Json, Path, State},
+ http::StatusCode,
+ response::{self, IntoResponse},
+};
+
+use crate::{
+ app::App,
+ clock::RequestedAt,
+ error::{Internal, NotFound},
+ message::{self, app::DeleteError},
+ token::extract::Identity,
+};
+
+#[cfg(test)]
+mod test;
+
+pub async fn handler(
+ State(app): State<App>,
+ Path(message): Path<message::Id>,
+ RequestedAt(deleted_at): RequestedAt,
+ identity: Identity,
+) -> Result<Response, Error> {
+ app.messages()
+ .delete(&identity.user, &message, &deleted_at)
+ .await?;
+
+ Ok(Response { id: message })
+}
+
+#[derive(Debug, serde::Serialize)]
+pub struct Response {
+ pub id: message::Id,
+}
+
+impl IntoResponse for Response {
+ fn into_response(self) -> response::Response {
+ (StatusCode::ACCEPTED, Json(self)).into_response()
+ }
+}
+
+#[derive(Debug, thiserror::Error)]
+#[error(transparent)]
+pub struct Error(#[from] pub DeleteError);
+
+impl IntoResponse for Error {
+ fn into_response(self) -> response::Response {
+ let Self(error) = self;
+ match error {
+ DeleteError::NotSender(_) => (StatusCode::FORBIDDEN, error.to_string()).into_response(),
+ DeleteError::NotFound(_) | DeleteError::Deleted(_) => NotFound(error).into_response(),
+ DeleteError::Database(_) => Internal::from(error).into_response(),
+ }
+ }
+}
diff --git a/src/message/routes/message/test.rs b/src/message/handlers/delete/test.rs
index 1888be7..15aa2c2 100644
--- a/src/message/routes/message/test.rs
+++ b/src/message/handlers/delete/test.rs
@@ -1,6 +1,5 @@
use axum::extract::{Path, State};
-use super::delete;
use crate::{message::app, test::fixtures};
#[tokio::test]
@@ -14,7 +13,7 @@ pub async fn delete_message() {
// Send the request
- let response = delete::handler(
+ let response = super::handler(
State(app.clone()),
Path(message.id.clone()),
fixtures::now(),
@@ -43,7 +42,7 @@ pub async fn delete_invalid_message_id() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let message = fixtures::message::fictitious();
- let delete::Error(error) = delete::handler(
+ let super::Error(error) = super::handler(
State(app.clone()),
Path(message.clone()),
fixtures::now(),
@@ -74,7 +73,7 @@ pub async fn delete_deleted() {
// Send the request
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
- let delete::Error(error) = delete::handler(
+ let super::Error(error) = super::handler(
State(app.clone()),
Path(message.id.clone()),
fixtures::now(),
@@ -105,7 +104,7 @@ pub async fn delete_expired() {
// Send the request
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
- let delete::Error(error) = delete::handler(
+ let super::Error(error) = super::handler(
State(app.clone()),
Path(message.id.clone()),
fixtures::now(),
@@ -141,7 +140,7 @@ pub async fn delete_purged() {
// Send the request
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
- let delete::Error(error) = delete::handler(
+ let super::Error(error) = super::handler(
State(app.clone()),
Path(message.id.clone()),
fixtures::now(),
@@ -167,7 +166,7 @@ pub async fn delete_not_sender() {
// Send the request
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
- let delete::Error(error) = delete::handler(
+ let super::Error(error) = super::handler(
State(app.clone()),
Path(message.id.clone()),
fixtures::now(),
diff --git a/src/message/handlers/mod.rs b/src/message/handlers/mod.rs
new file mode 100644
index 0000000..7e78475
--- /dev/null
+++ b/src/message/handlers/mod.rs
@@ -0,0 +1,3 @@
+mod delete;
+
+pub use delete::handler as delete;
diff --git a/src/message/mod.rs b/src/message/mod.rs
index c2687bc..e1643e6 100644
--- a/src/message/mod.rs
+++ b/src/message/mod.rs
@@ -1,12 +1,10 @@
pub mod app;
mod body;
pub mod event;
+pub mod handlers;
mod history;
mod id;
pub mod repo;
-mod routes;
mod snapshot;
-pub use self::{
- body::Body, event::Event, history::History, id::Id, routes::router, snapshot::Message,
-};
+pub use self::{body::Body, event::Event, history::History, id::Id, snapshot::Message};
diff --git a/src/message/routes/message/mod.rs b/src/message/routes/message/mod.rs
deleted file mode 100644
index a05d344..0000000
--- a/src/message/routes/message/mod.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-#[cfg(test)]
-mod test;
-
-pub mod delete {
- use axum::{
- extract::{Json, Path, State},
- http::StatusCode,
- response::{self, IntoResponse},
- };
-
- use crate::{
- app::App,
- clock::RequestedAt,
- error::{Internal, NotFound},
- message::{self, app::DeleteError},
- token::extract::Identity,
- };
-
- pub async fn handler(
- State(app): State<App>,
- Path(message): Path<message::Id>,
- RequestedAt(deleted_at): RequestedAt,
- identity: Identity,
- ) -> Result<Response, Error> {
- app.messages()
- .delete(&identity.user, &message, &deleted_at)
- .await?;
-
- Ok(Response { id: message })
- }
-
- #[derive(Debug, serde::Serialize)]
- pub struct Response {
- pub id: message::Id,
- }
-
- impl IntoResponse for Response {
- fn into_response(self) -> response::Response {
- (StatusCode::ACCEPTED, Json(self)).into_response()
- }
- }
-
- #[derive(Debug, thiserror::Error)]
- #[error(transparent)]
- pub struct Error(#[from] pub DeleteError);
-
- impl IntoResponse for Error {
- fn into_response(self) -> response::Response {
- let Self(error) = self;
- match error {
- DeleteError::NotSender(_) => {
- (StatusCode::FORBIDDEN, error.to_string()).into_response()
- }
- DeleteError::NotFound(_) | DeleteError::Deleted(_) => {
- NotFound(error).into_response()
- }
- DeleteError::Database(_) => Internal::from(error).into_response(),
- }
- }
- }
-}
diff --git a/src/message/routes/mod.rs b/src/message/routes/mod.rs
deleted file mode 100644
index 00b2b1a..0000000
--- a/src/message/routes/mod.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use axum::{Router, routing::delete};
-
-use crate::app::App;
-
-mod message;
-
-pub fn router() -> Router<App> {
- Router::new().route("/api/messages/{message}", delete(message::delete::handler))
-}