diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index 389f7ce91c..64c631ff01 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -657,11 +657,16 @@ impl RouteEnum { #[allow(non_camel_case_types)] #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Debug, PartialEq)] pub enum #match_error_name { #(#error_variants),* } + impl std::fmt::Debug for #match_error_name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}({})", stringify!(#match_error_name), self) + } + } + impl std::fmt::Display for #match_error_name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/packages/router-macro/src/segment.rs b/packages/router-macro/src/segment.rs index ba4cbfab8d..230517afea 100644 --- a/packages/router-macro/src/segment.rs +++ b/packages/router-macro/src/segment.rs @@ -279,13 +279,18 @@ pub(crate) fn create_error_type( quote! { #[allow(non_camel_case_types)] #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Debug, PartialEq)] pub enum #error_name { ExtraSegments(String), #(#child_type_variant,)* #(#error_variants,)* } + impl std::fmt::Debug for #error_name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}({})", stringify!(#error_name), self) + } + } + impl std::fmt::Display for #error_name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/packages/router/src/routable.rs b/packages/router/src/routable.rs index e61c6b4b63..6eaaa3f1ab 100644 --- a/packages/router/src/routable.rs +++ b/packages/router/src/routable.rs @@ -364,8 +364,8 @@ fn full_circle() { /// } /// /// // Implement ToRouteSegments for NumericRouteSegments so that we can display the route segments -/// impl ToRouteSegments for &NumericRouteSegments { -/// fn display_route_segments(self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +/// impl ToRouteSegments for NumericRouteSegments { +/// fn display_route_segments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { /// for number in &self.numbers { /// write!(f, "/{}", number)?; /// } @@ -391,24 +391,18 @@ fn full_circle() { /// # todo!() /// # } /// ``` -#[rustversion::attr( - since(1.78.0), - diagnostic::on_unimplemented( - message = "`ToRouteSegments` is not implemented for `{Self}`", - label = "route segment", - note = "ToRouteSegments is automatically implemented for types that implement `IntoIterator` with an `Item` type that implements `Display`. You need to either implement IntoIterator or implement ToRouteSegments manually." - ) -)] pub trait ToRouteSegments { - /// Display the route segments. You must url encode the segments. - fn display_route_segments(self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result; + /// Display the route segments with each route segment separated by a `/`. This should not start with a `/`. + /// + fn display_route_segments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result; } +// Implement ToRouteSegments for any type that can turn &self into an iterator of &T where T: Display impl ToRouteSegments for I where - I: IntoIterator, + for<'a> &'a I: IntoIterator, { - fn display_route_segments(self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn display_route_segments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for segment in self { write!(f, "/")?; let segment = segment.to_string(); @@ -460,8 +454,8 @@ fn to_route_segments() { /// } /// /// // Implement ToRouteSegments for NumericRouteSegments so that we can display the route segments -/// impl ToRouteSegments for &NumericRouteSegments { -/// fn display_route_segments(self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +/// impl ToRouteSegments for NumericRouteSegments { +/// fn display_route_segments(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { /// for number in &self.numbers { /// write!(f, "/{}", number)?; /// } @@ -497,9 +491,11 @@ fn to_route_segments() { )] pub trait FromRouteSegments: Sized { /// The error that can occur when parsing route segments. - type Err; + type Err: std::fmt::Display; /// Create an instance of `Self` from route segments. + /// + /// NOTE: This method must parse the output of `ToRouteSegments::display_route_segments` into the type `Self`. fn from_route_segments(segments: &[&str]) -> Result; }