diff --git a/Cargo.toml b/Cargo.toml index 4882769..6a2cbf8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,5 +30,8 @@ pin-project-lite = { version = "0.2", optional = true } serde = { version = "1", features = ["derive"], optional = true } serde_json = { version = "1", optional = true } +[dev-dependencies] +axum = { version = "0.7.1", default-features = false } + [package.metadata.docs.rs] all-features = true diff --git a/README.md b/README.md index e49a677..1ced135 100644 --- a/README.md +++ b/README.md @@ -74,11 +74,9 @@ any of your responses. | `HX-Reswap` | `HxReswap` | `axum_htmx::responders::SwapOption` | | `HX-Retarget` | `HxRetarget` | `String` | | `HX-Reselect` | `HxReselect` | `String` | -| `HX-Trigger` | `HxResponseTrigger` | `String` or `axum_htmx::serde::HxEvent`* | -| `HX-Trigger-After-Settle` | `HxResponseTriggerAfterSettle` | `String` or `axum_htmx::serde::HxEvent`* | -| `HX-Trigger-After-Swap` | `HxResponseTriggerAfterSwap` | `String` or `axum_htmx::serde::HxEvent`* | - -_* requires the `serde` feature flag to be enabled._ +| `HX-Trigger` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` | +| `HX-Trigger-After-Settle` | `HxResponseTriggerAfterSettle` | `axum_htmx::serde::HxEvent` | +| `HX-Trigger-After-Swap` | `HxResponseTriggerAfterSwap` | `axum_htmx::serde::HxEvent` | ## Request Guards @@ -137,7 +135,7 @@ use axum_htmx::HxResponseTrigger; async fn index() -> (&'static str, HxResponseTrigger) { ( "Hello, world!", - HxResponseTrigger(vec!["my-event".to_string()]), + HxResponseTrigger::from(["my-event", "second-event"]), ) } ``` @@ -146,16 +144,16 @@ async fn index() -> (&'static str, HxResponseTrigger) { can use via the `serde` feature flag and the `HxEvent` type. ```rust -use axum_htmx::serde::HxEvent; use serde_json::json; // Note that we are using `HxResponseTrigger` from the `axum_htmx::serde` module // instead of the root module. -use axum_htmx::serde::HxResponseTrigger; +use axum_htmx::{HxEvent, HxResponseTrigger}; async fn index() -> (&'static str, HxResponseTrigger) { let event = HxEvent::new_with_data( "my-event", + // May be any object that implements `serde::Serialize` json!({"level": "info", "message": { "title": "Hello, world!", "body": "This is a test message.", @@ -188,10 +186,10 @@ fn router_two() -> Router { ## Feature Flags -| Flag | Default | Description | Dependencies | -|----------|----------|------------------------------------------------------------------------------------|---------------------------------------------| -| `guards` | Disabled | Adds request guard layers. | `tower`, `futures-core`, `pin-project-lite` | -| `serde` | Disabled | Adds serde support for the `HxResponseTrigger*` and `HxLocation` response headers. | `serde`, `serde_json` | +| Flag | Default | Description | Dependencies | +|----------|----------|------------------------------------------------------------|---------------------------------------------| +| `guards` | Disabled | Adds request guard layers. | `tower`, `futures-core`, `pin-project-lite` | +| `serde` | Disabled | Adds serde support for the `HxEvent` and `LocationOptions` | `serde`, `serde_json` | ## Contributing diff --git a/src/responders/trigger.rs b/src/responders/trigger.rs index 647a75c..82cb71f 100644 --- a/src/responders/trigger.rs +++ b/src/responders/trigger.rs @@ -23,7 +23,7 @@ impl HxEvent { } } - /// Creates new event with event data. + /// Creates new event with data. #[cfg(feature = "serde")] #[cfg_attr(feature = "unstable", doc(cfg(feature = "serde")))] pub fn new_with_data( @@ -116,8 +116,10 @@ impl IntoResponseParts for HxResponseTrigger { type Error = HxError; fn into_response_parts(self, mut res: ResponseParts) -> Result { - res.headers_mut() - .insert(headers::HX_TRIGGER, events_to_header_value(self.0)?); + if !self.0.is_empty() { + res.headers_mut() + .insert(headers::HX_TRIGGER, events_to_header_value(self.0)?); + } Ok(res) } @@ -148,8 +150,10 @@ impl IntoResponseParts for HxResponseTriggerAfterSettle { type Error = HxError; fn into_response_parts(self, mut res: ResponseParts) -> Result { - res.headers_mut() - .insert(headers::HX_TRIGGER, events_to_header_value(self.0)?); + if !self.0.is_empty() { + res.headers_mut() + .insert(headers::HX_TRIGGER, events_to_header_value(self.0)?); + } Ok(res) } @@ -180,8 +184,10 @@ impl IntoResponseParts for HxResponseTriggerAfterSwap { type Error = HxError; fn into_response_parts(self, mut res: ResponseParts) -> Result { - res.headers_mut() - .insert(headers::HX_TRIGGER, events_to_header_value(self.0)?); + if !self.0.is_empty() { + res.headers_mut() + .insert(headers::HX_TRIGGER, events_to_header_value(self.0)?); + } Ok(res) } @@ -210,5 +216,8 @@ mod tests { let expected_value = r#"{"my-event":{"level":"info","message":{"body":"This is a test message.","title":"Hello, world!"}}}"#; assert_eq!(header_value, HeaderValue::from_static(expected_value)); + + let value = events_to_header_value(HxResponseTrigger::from(["foo", "bar"]).0).unwrap(); + assert_eq!(value, HeaderValue::from_static("foo, bar")); } }