From 28b495ca43507b5bff519b82febd5ff04c1a652d Mon Sep 17 00:00:00 2001 From: Dmitry Kudryavtsev Date: Mon, 2 Jun 2025 21:32:43 +0200 Subject: [PATCH 1/2] remove `Uri` from responders - replace with `String` --- README.md | 8 ++-- src/responders.rs | 52 +++++++------------------- src/responders/location.rs | 75 +++++++++----------------------------- 3 files changed, 36 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index ab39236..fdd0726 100644 --- a/README.md +++ b/README.md @@ -65,11 +65,11 @@ any of your responses. | Header | Responder | Value | |---------------------------|---------------------|-------------------------------------| -| `HX-Location` | `HxLocation` | `axum::http::Uri` | -| `HX-Push-Url` | `HxPushUrl` | `axum::http::Uri` | -| `HX-Redirect` | `HxRedirect` | `axum::http::Uri` | +| `HX-Location` | `HxLocation` | `String` | +| `HX-Push-Url` | `HxPushUrl` | `String` | +| `HX-Redirect` | `HxRedirect` | `String` | | `HX-Refresh` | `HxRefresh` | `bool` | -| `HX-Replace-Url` | `HxReplaceUrl` | `axum::http::Uri` | +| `HX-Replace-Url` | `HxReplaceUrl` | `String` | | `HX-Reswap` | `HxReswap` | `axum_htmx::responders::SwapOption` | | `HX-Retarget` | `HxRetarget` | `String` | | `HX-Reselect` | `HxReselect` | `String` | diff --git a/src/responders.rs b/src/responders.rs index e7de8d2..a6caf7c 100644 --- a/src/responders.rs +++ b/src/responders.rs @@ -1,9 +1,9 @@ //! Axum responses for htmx response headers. -use std::{convert::Infallible, str::FromStr}; +use std::convert::Infallible; use axum_core::response::{IntoResponseParts, ResponseParts}; -use http::{HeaderValue, Uri}; +use http::HeaderValue; use crate::{headers, HxError}; @@ -32,7 +32,7 @@ const HX_SWAP_NONE: &str = "none"; /// /// See for more information. #[derive(Debug, Clone)] -pub struct HxPushUrl(pub Uri); +pub struct HxPushUrl(pub String); impl IntoResponseParts for HxPushUrl { type Error = HxError; @@ -47,17 +47,9 @@ impl IntoResponseParts for HxPushUrl { } } -impl From for HxPushUrl { - fn from(uri: Uri) -> Self { - Self(uri) - } -} - -impl<'a> TryFrom<&'a str> for HxPushUrl { - type Error = ::Err; - - fn try_from(value: &'a str) -> Result { - Ok(Self(value.parse()?)) +impl<'a> From<&'a str> for HxPushUrl { + fn from(value: &'a str) -> Self { + Self(value.to_string()) } } @@ -68,7 +60,7 @@ impl<'a> TryFrom<&'a str> for HxPushUrl { /// Will fail if the supplied Uri contains characters that are not visible ASCII /// (32-127). #[derive(Debug, Clone)] -pub struct HxRedirect(pub Uri); +pub struct HxRedirect(pub String); impl IntoResponseParts for HxRedirect { type Error = HxError; @@ -83,17 +75,9 @@ impl IntoResponseParts for HxRedirect { } } -impl From for HxRedirect { - fn from(uri: Uri) -> Self { - Self(uri) - } -} - -impl<'a> TryFrom<&'a str> for HxRedirect { - type Error = ::Err; - - fn try_from(value: &'a str) -> Result { - Ok(Self(value.parse()?)) +impl<'a> From<&'a str> for HxRedirect { + fn from(value: &'a str) -> Self { + Self(value.to_string()) } } @@ -137,7 +121,7 @@ impl IntoResponseParts for HxRefresh { /// /// See for more information. #[derive(Debug, Clone)] -pub struct HxReplaceUrl(pub Uri); +pub struct HxReplaceUrl(pub String); impl IntoResponseParts for HxReplaceUrl { type Error = HxError; @@ -152,17 +136,9 @@ impl IntoResponseParts for HxReplaceUrl { } } -impl From for HxReplaceUrl { - fn from(uri: Uri) -> Self { - Self(uri) - } -} - -impl<'a> TryFrom<&'a str> for HxReplaceUrl { - type Error = ::Err; - - fn try_from(value: &'a str) -> Result { - Ok(Self(value.parse()?)) +impl<'a> From<&'a str> for HxReplaceUrl { + fn from(value: &'a str) -> Self { + Self(value.to_string()) } } diff --git a/src/responders/location.rs b/src/responders/location.rs index 92c2a82..744a613 100644 --- a/src/responders/location.rs +++ b/src/responders/location.rs @@ -1,7 +1,5 @@ -use std::str::FromStr; - use axum_core::response::{IntoResponseParts, ResponseParts}; -use http::{HeaderValue, Uri}; +use http::HeaderValue; use crate::{headers, HxError}; @@ -12,14 +10,14 @@ use crate::{headers, HxError}; /// target on the page, you must enable the `serde` feature flag and specify /// [`LocationOptions`]. /// -/// Will fail if the supplied Uri contains characters that are not visible ASCII +/// Will fail if the supplied uri contains characters that are not visible ASCII /// (32-127). /// /// See for more information. #[derive(Debug, Clone)] pub struct HxLocation { /// Uri of the new location. - pub uri: Uri, + pub uri: String, /// Extra options. #[cfg(feature = "serde")] #[cfg_attr(feature = "unstable", doc(cfg(feature = "serde")))] @@ -27,43 +25,24 @@ pub struct HxLocation { } impl HxLocation { - /// Creates location from [`Uri`] without any options. - pub fn from_uri(uri: Uri) -> Self { - Self { - #[cfg(feature = "serde")] - options: LocationOptions::default(), - uri, - } - } - - /// Creates location from [`Uri`] and options. - #[cfg(feature = "serde")] - #[cfg_attr(feature = "unstable", doc(cfg(feature = "serde")))] - pub fn from_uri_with_options(uri: Uri, options: LocationOptions) -> Self { - Self { uri, options } - } - /// Parses `uri` and sets it as location. #[allow(clippy::should_implement_trait)] - pub fn from_str(uri: impl AsRef) -> Result { - Ok(Self { + pub fn from_str(uri: impl AsRef) -> Self { + Self { #[cfg(feature = "serde")] options: LocationOptions::default(), - uri: uri.as_ref().parse::()?, - }) + uri: uri.as_ref().to_string(), + } } /// Parses `uri` and sets it as location with additional options. #[cfg(feature = "serde")] #[cfg_attr(feature = "unstable", doc(cfg(feature = "serde")))] - pub fn from_str_with_options( - uri: impl AsRef, - options: LocationOptions, - ) -> Result { - Ok(Self { + pub fn from_str_with_options(uri: impl AsRef, options: LocationOptions) -> Self { + Self { options, - uri: uri.as_ref().parse::()?, - }) + uri: uri.as_ref().to_string(), + } } #[cfg(feature = "serde")] @@ -88,34 +67,16 @@ impl HxLocation { } } -impl From for HxLocation { - fn from(uri: Uri) -> Self { - Self::from_uri(uri) - } -} - -#[cfg(feature = "serde")] -#[cfg_attr(feature = "unstable", doc(cfg(feature = "serde")))] -impl From<(Uri, LocationOptions)> for HxLocation { - fn from((uri, options): (Uri, LocationOptions)) -> Self { - Self::from_uri_with_options(uri, options) - } -} - -impl<'a> TryFrom<&'a str> for HxLocation { - type Error = ::Err; - - fn try_from(uri: &'a str) -> Result { +impl<'a> From<&'a str> for HxLocation { + fn from(uri: &'a str) -> Self { Self::from_str(uri) } } #[cfg(feature = "serde")] #[cfg_attr(feature = "unstable", doc(cfg(feature = "serde")))] -impl<'a> TryFrom<(&'a str, LocationOptions)> for HxLocation { - type Error = ::Err; - - fn try_from((uri, options): (&'a str, LocationOptions)) -> Result { +impl<'a> From<(&'a str, LocationOptions)> for HxLocation { + fn from((uri, options): (&'a str, LocationOptions)) -> Self { Self::from_str_with_options(uri, options) } } @@ -207,11 +168,11 @@ mod tests { fn test_serialize_location() { use crate::SwapOption; - let loc = HxLocation::try_from("/foo").unwrap(); + let loc = HxLocation::from("/foo"); assert_eq!(loc.into_header_with_options().unwrap(), "/foo"); - let loc = HxLocation::from_uri_with_options( - "/foo".parse().unwrap(), + let loc = HxLocation::from_str_with_options( + "/foo", LocationOptions { event: Some("click".into()), swap: Some(SwapOption::InnerHtml), From e3be9e620e5995fba126bc82f1811ec201c41d34 Mon Sep 17 00:00:00 2001 From: Dmitry Kudryavtsev Date: Mon, 2 Jun 2025 21:41:53 +0200 Subject: [PATCH 2/2] clean clippy warnings --- src/responders.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/responders.rs b/src/responders.rs index a6caf7c..69e0abe 100644 --- a/src/responders.rs +++ b/src/responders.rs @@ -40,7 +40,7 @@ impl IntoResponseParts for HxPushUrl { fn into_response_parts(self, mut res: ResponseParts) -> Result { res.headers_mut().insert( headers::HX_PUSH_URL, - HeaderValue::from_maybe_shared(self.0.to_string())?, + HeaderValue::from_maybe_shared(self.0)?, ); Ok(res) @@ -68,7 +68,7 @@ impl IntoResponseParts for HxRedirect { fn into_response_parts(self, mut res: ResponseParts) -> Result { res.headers_mut().insert( headers::HX_REDIRECT, - HeaderValue::from_maybe_shared(self.0.to_string())?, + HeaderValue::from_maybe_shared(self.0)?, ); Ok(res) @@ -129,7 +129,7 @@ impl IntoResponseParts for HxReplaceUrl { fn into_response_parts(self, mut res: ResponseParts) -> Result { res.headers_mut().insert( headers::HX_REPLACE_URL, - HeaderValue::from_maybe_shared(self.0.to_string())?, + HeaderValue::from_maybe_shared(self.0)?, ); Ok(res)