feat(axum): add concise interaction request dispatch
Wrap extracted interaction forms in an InteractionRequest with a concise dispatch path, add a handlers() helper, and move canonical examples off direct HandlerRegistry/InteractionForm plumbing. req: axum_integration/003 req: ceremony/001 req: dx/003 req: examples/003
This commit is contained in:
@@ -136,6 +136,15 @@ pub struct InteractionForm {
|
||||
files: Vec<InteractionFile>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct InteractionRequest {
|
||||
form: InteractionForm,
|
||||
}
|
||||
|
||||
pub trait DispatchRegistry {
|
||||
fn dispatch_form(self, form: InteractionForm) -> Result<EffectResponse, DispatchRejection>;
|
||||
}
|
||||
|
||||
pub struct HandlerRegistry {
|
||||
fingerprint: BuildFingerprint,
|
||||
handlers: BTreeMap<u32, Box<dyn Fn(InteractionForm) -> EffectBatch + Send + Sync>>,
|
||||
@@ -253,6 +262,29 @@ impl InteractionForm {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn handlers(fingerprint: BuildFingerprint) -> HandlerRegistry {
|
||||
HandlerRegistry::new(fingerprint)
|
||||
}
|
||||
|
||||
impl InteractionRequest {
|
||||
pub fn dispatch(
|
||||
self,
|
||||
registry: impl DispatchRegistry,
|
||||
) -> Result<EffectResponse, DispatchRejection> {
|
||||
registry.dispatch_form(self.form)
|
||||
}
|
||||
|
||||
pub fn form(&self) -> &InteractionForm {
|
||||
&self.form
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InteractionForm> for InteractionRequest {
|
||||
fn from(form: InteractionForm) -> Self {
|
||||
Self { form }
|
||||
}
|
||||
}
|
||||
|
||||
impl HandlerRegistry {
|
||||
pub const fn new(fingerprint: BuildFingerprint) -> Self {
|
||||
Self {
|
||||
@@ -303,6 +335,12 @@ impl HandlerRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
impl DispatchRegistry for HandlerRegistry {
|
||||
fn dispatch_form(self, form: InteractionForm) -> Result<EffectResponse, DispatchRejection> {
|
||||
self.dispatch(form)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for InteractionFormRejection {
|
||||
fn into_response(self) -> axum::response::Response {
|
||||
let (status, message) = match self {
|
||||
@@ -314,6 +352,20 @@ impl IntoResponse for InteractionFormRejection {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<S> FromRequest<S> for InteractionRequest
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = InteractionFormRejection;
|
||||
|
||||
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
|
||||
InteractionForm::from_request(req, state)
|
||||
.await
|
||||
.map(|form| Self { form })
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<S> FromRequest<S> for InteractionForm
|
||||
where
|
||||
|
||||
Reference in New Issue
Block a user