feat(axum): start stateful interactions tersely
Add state_interactions as a small helper for app-owned stateful registries, and use it in the workout exemplar to remove one layer of repetitive route wiring without hiding generated handles or app handlers. req: axum_integration/003 req: ceremony/001 req: dx/003 req: codegen/002 req: examples/001
This commit is contained in:
@@ -460,6 +460,14 @@ pub const fn interactions(fingerprint: BuildFingerprint) -> HandlerRegistry {
|
||||
HandlerRegistry::new(fingerprint)
|
||||
}
|
||||
|
||||
pub fn state_interactions<S>(fingerprint: BuildFingerprint, state: S) -> StateHandlerRegistry<S>
|
||||
where
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
// req: axum_integration/003 req: ceremony/001
|
||||
interactions(fingerprint).with_state(state)
|
||||
}
|
||||
|
||||
impl InteractionRequest {
|
||||
pub fn dispatch(
|
||||
self,
|
||||
|
||||
@@ -232,6 +232,47 @@ fn interaction_request_dispatches_with_concise_handlers_helper() {
|
||||
assert_eq!(response.batch.ops, vec![Slot::<String>::new(3).text("ok")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn state_interactions_starts_stateful_wiring_without_nested_closures() {
|
||||
// req: axum_integration/003 req: ceremony/001 req: dx/003
|
||||
fn ping(prefix: String) -> impl IntoEffect {
|
||||
Slot::<String>::new(3).text(format!("{prefix}: ping"))
|
||||
}
|
||||
|
||||
fn open(prefix: String, input: OpenProject) -> impl IntoEffect {
|
||||
Slot::<String>::new(3).text(format!("{prefix}: {}", input.project_id.0))
|
||||
}
|
||||
|
||||
let registry = || {
|
||||
hemx_axum::state_interactions(BuildFingerprint(4), "project".to_owned())
|
||||
.on_state(Handle::<()>::new(7), ping)
|
||||
.on(Handle::<()>::new(8), open)
|
||||
.into_registry()
|
||||
};
|
||||
|
||||
let ping_response = InteractionRequest::from(InteractionForm::for_handle(
|
||||
Handle::<()>::new(7),
|
||||
Vec::new(),
|
||||
))
|
||||
.dispatch(registry())
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
ping_response.batch.ops,
|
||||
vec![Slot::<String>::new(3).text("project: ping")]
|
||||
);
|
||||
|
||||
let open_response = InteractionRequest::from(InteractionForm::for_handle(
|
||||
Handle::<()>::new(8),
|
||||
vec![("project_id".to_owned(), "42".to_owned())],
|
||||
))
|
||||
.dispatch(registry())
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
open_response.batch.ops,
|
||||
vec![Slot::<String>::new(3).text("project: 42")]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interaction_request_dispatches_typed_form_inputs() {
|
||||
// req: axum_integration/003 req: form/004 req: canonical_authoring/003
|
||||
|
||||
Reference in New Issue
Block a user