From a35436ee4f5b7925c2e2d902d07904dc7e9b6796 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 7 Jun 2024 21:40:50 +0200 Subject: [PATCH] Change ToRouteSegments to borrow self (#2283) * Change display route segments to borrow the type * fix formatting --- packages/router-macro/src/lib.rs | 7 ++++++- packages/router-macro/src/segment.rs | 7 ++++++- packages/router/src/routable.rs | 30 ++++++++++++---------------- 3 files changed, 25 insertions(+), 19 deletions(-) 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; }