split RouterExt impl related into ruma_wrapper unit.

slightly restrict client_server mod index.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-05-28 04:52:58 +00:00
parent f1d1366129
commit 5fe5ab279c
5 changed files with 149 additions and 142 deletions

View file

@ -1,76 +1,76 @@
pub(crate) mod account; pub(super) mod account;
pub(crate) mod alias; pub(super) mod alias;
pub(crate) mod backup; pub(super) mod backup;
pub(crate) mod capabilities; pub(super) mod capabilities;
pub(crate) mod config; pub(super) mod config;
pub(crate) mod context; pub(super) mod context;
pub(crate) mod device; pub(super) mod device;
pub(crate) mod directory; pub(super) mod directory;
pub(crate) mod filter; pub(super) mod filter;
pub(crate) mod keys; pub(super) mod keys;
pub(crate) mod media; pub(super) mod media;
pub(crate) mod membership; pub(super) mod membership;
pub(crate) mod message; pub(super) mod message;
pub(crate) mod presence; pub(super) mod presence;
pub(crate) mod profile; pub(super) mod profile;
pub(crate) mod push; pub(super) mod push;
pub(crate) mod read_marker; pub(super) mod read_marker;
pub(crate) mod redact; pub(super) mod redact;
pub(crate) mod relations; pub(super) mod relations;
pub(crate) mod report; pub(super) mod report;
pub(crate) mod room; pub(super) mod room;
pub(crate) mod search; pub(super) mod search;
pub(crate) mod session; pub(super) mod session;
pub(crate) mod space; pub(super) mod space;
pub(crate) mod state; pub(super) mod state;
pub(crate) mod sync; pub(super) mod sync;
pub(crate) mod tag; pub(super) mod tag;
pub(crate) mod thirdparty; pub(super) mod thirdparty;
pub(crate) mod threads; pub(super) mod threads;
pub(crate) mod to_device; pub(super) mod to_device;
pub(crate) mod typing; pub(super) mod typing;
pub(crate) mod unstable; pub(super) mod unstable;
pub(crate) mod unversioned; pub(super) mod unversioned;
pub(crate) mod user_directory; pub(super) mod user_directory;
pub(crate) mod voip; pub(super) mod voip;
pub(crate) use account::*; pub(super) use account::*;
pub use alias::get_alias_helper; pub use alias::get_alias_helper;
pub(crate) use alias::*; pub(super) use alias::*;
pub(crate) use backup::*; pub(super) use backup::*;
pub(crate) use capabilities::*; pub(super) use capabilities::*;
pub(crate) use config::*; pub(super) use config::*;
pub(crate) use context::*; pub(super) use context::*;
pub(crate) use device::*; pub(super) use device::*;
pub(crate) use directory::*; pub(super) use directory::*;
pub(crate) use filter::*; pub(super) use filter::*;
pub(crate) use keys::*; pub(super) use keys::*;
pub(crate) use media::*; pub(super) use media::*;
pub(crate) use membership::*; pub(super) use membership::*;
pub use membership::{join_room_by_id_helper, leave_all_rooms, leave_room}; pub use membership::{join_room_by_id_helper, leave_all_rooms, leave_room};
pub(crate) use message::*; pub(super) use message::*;
pub(crate) use presence::*; pub(super) use presence::*;
pub(crate) use profile::*; pub(super) use profile::*;
pub(crate) use push::*; pub(super) use push::*;
pub(crate) use read_marker::*; pub(super) use read_marker::*;
pub(crate) use redact::*; pub(super) use redact::*;
pub(crate) use relations::*; pub(super) use relations::*;
pub(crate) use report::*; pub(super) use report::*;
pub(crate) use room::*; pub(super) use room::*;
pub(crate) use search::*; pub(super) use search::*;
pub(crate) use session::*; pub(super) use session::*;
pub(crate) use space::*; pub(super) use space::*;
pub(crate) use state::*; pub(super) use state::*;
pub(crate) use sync::*; pub(super) use sync::*;
pub(crate) use tag::*; pub(super) use tag::*;
pub(crate) use thirdparty::*; pub(super) use thirdparty::*;
pub(crate) use threads::*; pub(super) use threads::*;
pub(crate) use to_device::*; pub(super) use to_device::*;
pub(crate) use typing::*; pub(super) use typing::*;
pub(crate) use unstable::*; pub(super) use unstable::*;
pub(crate) use unversioned::*; pub(super) use unversioned::*;
pub(crate) use user_directory::*; pub(super) use user_directory::*;
pub(crate) use voip::*; pub(super) use voip::*;
/// generated device ID length /// generated device ID length
const DEVICE_ID_LENGTH: usize = 10; const DEVICE_ID_LENGTH: usize = 10;

View file

@ -7,8 +7,8 @@ extern crate conduit_core as conduit;
extern crate conduit_service as service; extern crate conduit_service as service;
pub use client_server::membership::{join_room_by_id_helper, leave_all_rooms}; pub use client_server::membership::{join_room_by_id_helper, leave_all_rooms};
pub(crate) use conduit::{debug_error, debug_info, debug_warn, error::RumaResponse, utils, Error, Result}; pub(crate) use conduit::{debug_error, debug_info, debug_warn, utils, Error, Result};
pub(crate) use ruma_wrapper::Ruma; pub(crate) use ruma_wrapper::{Ruma, RumaResponse};
pub(crate) use service::{pdu::PduEvent, services, user_is_local}; pub(crate) use service::{pdu::PduEvent, services, user_is_local};
conduit::mod_ctor! {} conduit::mod_ctor! {}

View file

@ -1,15 +1,13 @@
use std::future::Future;
use axum::{ use axum::{
response::IntoResponse, response::IntoResponse,
routing::{any, get, on, post, MethodFilter}, routing::{any, get, post},
Router, Router,
}; };
use conduit::{Error, Result, Server}; use conduit::{Error, Server};
use http::{Method, Uri}; use http::Uri;
use ruma::api::{client::error::ErrorKind, IncomingRequest}; use ruma::api::client::error::ErrorKind;
use crate::{client_server, server_server, Ruma, RumaResponse}; use crate::{client_server, ruma_wrapper::RouterExt, server_server};
pub fn build(router: Router, server: &Server) -> Router { pub fn build(router: Router, server: &Server) -> Router {
let config = &server.config; let config = &server.config;
@ -234,66 +232,3 @@ async fn initial_sync(_uri: Uri) -> impl IntoResponse {
} }
async fn federation_disabled() -> impl IntoResponse { Error::bad_config("Federation is disabled.") } async fn federation_disabled() -> impl IntoResponse { Error::bad_config("Federation is disabled.") }
trait RouterExt {
fn ruma_route<H, T>(self, handler: H) -> Self
where
H: RumaHandler<T>,
T: 'static;
}
impl RouterExt for Router {
#[inline(always)]
fn ruma_route<H, T>(self, handler: H) -> Self
where
H: RumaHandler<T>,
T: 'static,
{
handler.add_routes(self)
}
}
trait RumaHandler<T> {
fn add_routes(&self, router: Router) -> Router;
fn add_route(&self, router: Router, path: &str) -> Router;
}
impl<Req, E, F, Fut> RumaHandler<Ruma<Req>> for F
where
Req: IncomingRequest + Send + 'static,
F: FnOnce(Ruma<Req>) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Req::OutgoingResponse, E>> + Send,
E: IntoResponse,
{
#[inline(always)]
fn add_routes(&self, router: Router) -> Router {
Req::METADATA
.history
.all_paths()
.fold(router, |router, path| self.add_route(router, path))
}
#[inline(always)]
fn add_route(&self, router: Router, path: &str) -> Router {
let handle = self.clone();
let method = method_to_filter(Req::METADATA.method);
let action = |req| async { handle(req).await.map(RumaResponse) };
router.route(path, on(method, action))
}
}
#[inline]
fn method_to_filter(method: Method) -> MethodFilter {
match method {
Method::DELETE => MethodFilter::DELETE,
Method::GET => MethodFilter::GET,
Method::HEAD => MethodFilter::HEAD,
Method::OPTIONS => MethodFilter::OPTIONS,
Method::PATCH => MethodFilter::PATCH,
Method::POST => MethodFilter::POST,
Method::PUT => MethodFilter::PUT,
Method::TRACE => MethodFilter::TRACE,
m => panic!("Unsupported HTTP method: {m:?}"),
}
}

View file

@ -1,11 +1,14 @@
mod auth; mod auth;
mod request; mod request;
mod router;
mod xmatrix; mod xmatrix;
use std::ops::Deref; use std::ops::Deref;
pub(super) use conduit::error::RumaResponse;
use ruma::{CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId}; use ruma::{CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId};
pub(super) use self::router::RouterExt;
use crate::service::appservice::RegistrationInfo; use crate::service::appservice::RegistrationInfo;
/// Extractor for Ruma request structs /// Extractor for Ruma request structs

View file

@ -0,0 +1,69 @@
use std::future::Future;
use axum::{
response::IntoResponse,
routing::{on, MethodFilter},
Router,
};
use conduit::Result;
use http::Method;
use ruma::api::IncomingRequest;
use super::{Ruma, RumaResponse};
pub(in super::super) trait RouterExt {
fn ruma_route<H, T>(self, handler: H) -> Self
where
H: RumaHandler<T>;
}
impl RouterExt for Router {
fn ruma_route<H, T>(self, handler: H) -> Self
where
H: RumaHandler<T>,
{
handler.add_routes(self)
}
}
pub(in super::super) trait RumaHandler<T> {
fn add_routes(&self, router: Router) -> Router;
fn add_route(&self, router: Router, path: &str) -> Router;
}
impl<Req, E, F, Fut> RumaHandler<Ruma<Req>> for F
where
Req: IncomingRequest + Send + 'static,
F: FnOnce(Ruma<Req>) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<Req::OutgoingResponse, E>> + Send,
E: IntoResponse,
{
fn add_routes(&self, router: Router) -> Router {
Req::METADATA
.history
.all_paths()
.fold(router, |router, path| self.add_route(router, path))
}
fn add_route(&self, router: Router, path: &str) -> Router {
let handle = self.clone();
let method = method_to_filter(&Req::METADATA.method);
let action = |req| async { handle(req).await.map(RumaResponse) };
router.route(path, on(method, action))
}
}
const fn method_to_filter(method: &Method) -> MethodFilter {
match *method {
Method::DELETE => MethodFilter::DELETE,
Method::GET => MethodFilter::GET,
Method::HEAD => MethodFilter::HEAD,
Method::OPTIONS => MethodFilter::OPTIONS,
Method::PATCH => MethodFilter::PATCH,
Method::POST => MethodFilter::POST,
Method::PUT => MethodFilter::PUT,
Method::TRACE => MethodFilter::TRACE,
_ => panic!("Unsupported HTTP method"),
}
}