axum_routing_htmx/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
//!
//! ## Basic usage
//! The following example demonstrates the basic usage of the library.
//! On top of any regular handler, you can add the [`route`] macro to create a typed route.
//! Any path- or query-parameters in the url will be type-checked at compile-time, and properly
//! extracted into the handler.
//!
//! ```
#![doc = include_str!("../examples/basic.rs")]
//! ```
//!
//! Some valid url's as get-methods are:
//! - `/item/1?amount=2&offset=3`
//! - `/item/1?amount=2`
//! - `/item/1?offset=3`
//! - `/item/500`
//!
use std::fmt::Display;
use axum::routing::MethodRouter;
// pub struct HtmxHandlerStruct<S = ()> {
// pub htmx_method: HtmxMethod,
// pub axum_path: &'static str,
// pub method_router: MethodRouter<S>,
// pub format_path: &'static str,
// }
pub trait HtmxHandler<S> {
fn axum_path(&self) -> &'static str;
fn method_router(&self) -> MethodRouter<S>;
}
#[non_exhaustive]
#[derive(Debug, PartialEq, Eq)]
pub enum HtmxMethod {
Get,
Post,
Delete,
Patch,
Put,
}
impl Display for HtmxMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
HtmxMethod::Get => "hx-get",
HtmxMethod::Post => "hx-post",
HtmxMethod::Delete => "hx-delete",
HtmxMethod::Patch => "hx-patch",
HtmxMethod::Put => "hx-put",
})
}
}
pub use axum_routing_htmx_macros::{hx_delete, hx_get, hx_patch, hx_post, hx_put};
/// A trait that allows typed routes, created with the `hx_` macros to
/// be added to an axum router.
pub trait HtmxRouter: Sized {
/// The state type of the router.
type State: Clone + Send + Sync + 'static;
/// Add an HTMX route to the router.
///
/// Typed handlers are functions that return [`HtmxHandler`].
fn htmx_route(self, handler: impl HtmxHandler<Self::State>) -> Self;
}
impl<S> HtmxRouter for axum::Router<S>
where
S: Send + Sync + Clone + 'static,
{
type State = S;
fn htmx_route(self, handler: impl HtmxHandler<Self::State>) -> Self {
self.route(handler.axum_path(), handler.method_router())
}
}