mirror of
https://github.com/robertwayne/axum-htmx
synced 2024-11-29 14:44:33 +01:00
Combined HxResposeTrigger* into one struct
This commit is contained in:
parent
f07518d5a2
commit
a04e131a69
2 changed files with 51 additions and 83 deletions
|
@ -75,8 +75,8 @@ any of your responses.
|
||||||
| `HX-Retarget` | `HxRetarget` | `String` |
|
| `HX-Retarget` | `HxRetarget` | `String` |
|
||||||
| `HX-Reselect` | `HxReselect` | `String` |
|
| `HX-Reselect` | `HxReselect` | `String` |
|
||||||
| `HX-Trigger` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
| `HX-Trigger` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
||||||
| `HX-Trigger-After-Settle` | `HxResponseTriggerAfterSettle` | `axum_htmx::serde::HxEvent` |
|
| `HX-Trigger-After-Settle` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
||||||
| `HX-Trigger-After-Swap` | `HxResponseTriggerAfterSwap` | `axum_htmx::serde::HxEvent` |
|
| `HX-Trigger-After-Swap` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
||||||
|
|
||||||
## Request Guards
|
## Request Guards
|
||||||
|
|
||||||
|
|
|
@ -91,24 +91,53 @@ fn events_to_header_value(events: Vec<HxEvent>) -> Result<http::HeaderValue, HxE
|
||||||
HeaderValue::from_maybe_shared(header_value).map_err(HxError::from)
|
HeaderValue::from_maybe_shared(header_value).map_err(HxError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `HX-Trigger` header.
|
/// Describes when should event be triggered.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum TriggerMode {
|
||||||
|
Normal,
|
||||||
|
AfterSettle,
|
||||||
|
AfterSwap,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `HX-Trigger*` header.
|
||||||
///
|
///
|
||||||
/// Allows you to trigger client-side events.
|
/// Allows you to trigger client-side events.
|
||||||
|
/// Corresponds to `HX-Trigger`, `HX-Trigger-After-Settle` and `HX-Trigger-After-Swap` headers.
|
||||||
|
/// To change when events trigger use appropriate `mode`.
|
||||||
///
|
///
|
||||||
/// Will fail if the supplied events contain or produce characters that are not
|
/// Will fail if the supplied events contain or produce characters that are not
|
||||||
/// visible ASCII (32-127) when serializing to JSON.
|
/// visible ASCII (32-127) when serializing to JSON.
|
||||||
///
|
///
|
||||||
/// See <https://htmx.org/headers/hx-trigger/> for more information.
|
/// See <https://htmx.org/headers/hx-trigger/> for more information.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct HxResponseTrigger(pub Vec<HxEvent>);
|
pub struct HxResponseTrigger {
|
||||||
|
pub mode: TriggerMode,
|
||||||
|
pub events: Vec<HxEvent>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> From<T> for HxResponseTrigger
|
impl HxResponseTrigger {
|
||||||
where
|
/// Creates new [trigger](https://htmx.org/headers/hx-trigger/) with specified mode and events.
|
||||||
T: IntoIterator,
|
pub fn new<T: Into<HxEvent>>(mode: TriggerMode, events: impl IntoIterator<Item = T>) -> Self {
|
||||||
T::Item: Into<HxEvent>,
|
Self {
|
||||||
{
|
mode,
|
||||||
fn from(value: T) -> Self {
|
events: events.into_iter().map(Into::into).collect(),
|
||||||
Self(value.into_iter().map(Into::into).collect())
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates new [normal](https://htmx.org/headers/hx-trigger/) trigger from events.
|
||||||
|
pub fn normal<T: Into<HxEvent>>(events: impl IntoIterator<Item = T>) -> Self {
|
||||||
|
Self::new(TriggerMode::Normal, events)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates new [after settle](https://htmx.org/headers/hx-trigger/) trigger from events.
|
||||||
|
pub fn after_settle<T: Into<HxEvent>>(events: impl IntoIterator<Item = T>) -> Self {
|
||||||
|
Self::new(TriggerMode::AfterSettle, events)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates new [after swap](https://htmx.org/headers/hx-trigger/) trigger from events.
|
||||||
|
pub fn after_swap<T: Into<HxEvent>>(events: impl IntoIterator<Item = T>) -> Self {
|
||||||
|
Self::new(TriggerMode::AfterSwap, events)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,77 +145,15 @@ impl IntoResponseParts for HxResponseTrigger {
|
||||||
type Error = HxError;
|
type Error = HxError;
|
||||||
|
|
||||||
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
|
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
|
||||||
if !self.0.is_empty() {
|
if !self.events.is_empty() {
|
||||||
|
let header = match self.mode {
|
||||||
|
TriggerMode::Normal => headers::HX_TRIGGER,
|
||||||
|
TriggerMode::AfterSettle => headers::HX_TRIGGER_AFTER_SETTLE,
|
||||||
|
TriggerMode::AfterSwap => headers::HX_TRIGGER_AFTER_SETTLE,
|
||||||
|
};
|
||||||
|
|
||||||
res.headers_mut()
|
res.headers_mut()
|
||||||
.insert(headers::HX_TRIGGER, events_to_header_value(self.0)?);
|
.insert(header, events_to_header_value(self.events)?);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The `HX-Trigger-After-Settle` header.
|
|
||||||
///
|
|
||||||
/// Allows you to trigger client-side events after the settle step.
|
|
||||||
///
|
|
||||||
/// Will fail if the supplied events contain or produce characters that are not
|
|
||||||
/// visible ASCII (32-127) when serializing to JSON.
|
|
||||||
///
|
|
||||||
/// See <https://htmx.org/headers/hx-trigger/> for more information.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct HxResponseTriggerAfterSettle(pub Vec<HxEvent>);
|
|
||||||
|
|
||||||
impl<T> From<T> for HxResponseTriggerAfterSettle
|
|
||||||
where
|
|
||||||
T: IntoIterator,
|
|
||||||
T::Item: Into<HxEvent>,
|
|
||||||
{
|
|
||||||
fn from(value: T) -> Self {
|
|
||||||
Self(value.into_iter().map(Into::into).collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoResponseParts for HxResponseTriggerAfterSettle {
|
|
||||||
type Error = HxError;
|
|
||||||
|
|
||||||
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
|
|
||||||
if !self.0.is_empty() {
|
|
||||||
res.headers_mut()
|
|
||||||
.insert(headers::HX_TRIGGER, events_to_header_value(self.0)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The `HX-Trigger-After-Swap` header.
|
|
||||||
///
|
|
||||||
/// Allows you to trigger client-side events after the swap step.
|
|
||||||
///
|
|
||||||
/// Will fail if the supplied events contain or produce characters that are not
|
|
||||||
/// visible ASCII (32-127) when serializing to JSON.
|
|
||||||
///
|
|
||||||
/// See <https://htmx.org/headers/hx-trigger/> for more information.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct HxResponseTriggerAfterSwap(pub Vec<HxEvent>);
|
|
||||||
|
|
||||||
impl<T> From<T> for HxResponseTriggerAfterSwap
|
|
||||||
where
|
|
||||||
T: IntoIterator,
|
|
||||||
T::Item: Into<HxEvent>,
|
|
||||||
{
|
|
||||||
fn from(value: T) -> Self {
|
|
||||||
Self(value.into_iter().map(Into::into).collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoResponseParts for HxResponseTriggerAfterSwap {
|
|
||||||
type Error = HxError;
|
|
||||||
|
|
||||||
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
|
|
||||||
if !self.0.is_empty() {
|
|
||||||
res.headers_mut()
|
|
||||||
.insert(headers::HX_TRIGGER, events_to_header_value(self.0)?);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
|
@ -217,7 +184,8 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(header_value, HeaderValue::from_static(expected_value));
|
assert_eq!(header_value, HeaderValue::from_static(expected_value));
|
||||||
|
|
||||||
let value = events_to_header_value(HxResponseTrigger::from(["foo", "bar"]).0).unwrap();
|
let value =
|
||||||
|
events_to_header_value(HxResponseTrigger::normal(["foo", "bar"]).events).unwrap();
|
||||||
assert_eq!(value, HeaderValue::from_static("foo, bar"));
|
assert_eq!(value, HeaderValue::from_static("foo, bar"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue