diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index 0ed7d2625..8a030bb73 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -642,8 +642,17 @@ impl RouteEnum { let error_name = route.error_ident(); let route_str = &route.route; + let comment = format!( + " An error that can occur when trying to parse the route [`{}::{}`] ('{}').", + self.name, + route_name, + route_str + ); - error_variants.push(quote! { #route_name(#error_name) }); + error_variants.push(quote! { + #[doc = #comment] + #route_name(#error_name) + }); display_match.push(quote! { Self::#route_name(err) => write!(f, "Route '{}' ('{}') did not match:\n{}", stringify!(#route_name), #route_str, err)? }); type_defs.push(route.error_type()); } @@ -651,8 +660,15 @@ impl RouteEnum { let error_variant = redirect.error_variant(); let error_name = redirect.error_ident(); let route_str = &redirect.route; + let comment = format!( + " An error that can occur when trying to parse the redirect '{}'.", + route_str.value() + ); - error_variants.push(quote! { #error_variant(#error_name) }); + error_variants.push(quote! { + #[doc = #comment] + #error_variant(#error_name) + }); display_match.push(quote! { Self::#error_variant(err) => write!(f, "Redirect '{}' ('{}') did not match:\n{}", stringify!(#error_name), #route_str, err)? }); type_defs.push(redirect.error_type()); } @@ -663,15 +679,28 @@ impl RouteEnum { let error_variant = nest.error_variant(); let error_name = nest.error_ident(); let route_str = &nest.route; + let comment = format!( + " An error that can occur when trying to parse the nested segment {} ('{}').", + error_name, route_str + ); - error_variants.push(quote! { #error_variant(#error_name) }); + error_variants.push(quote! { + #[doc = #comment] + #error_variant(#error_name) + }); display_match.push(quote! { Self::#error_variant(err) => write!(f, "Nest '{}' ('{}') did not match:\n{}", stringify!(#error_name), #route_str, err)? }); type_defs.push(nest.error_type()); } + let comment = format!( + " An error that can occur when trying to parse the route enum [`{}`].", + self.name + ); + quote! { #(#type_defs)* + #[doc = #comment] #[allow(non_camel_case_types)] #[allow(clippy::derive_partial_eq_without_eq)] pub enum #match_error_name { diff --git a/packages/router-macro/src/nest.rs b/packages/router-macro/src/nest.rs index 7b315c1d2..4a2b09c46 100644 --- a/packages/router-macro/src/nest.rs +++ b/packages/router-macro/src/nest.rs @@ -82,6 +82,6 @@ impl Nest { pub fn error_type(&self) -> TokenStream { let error_name = self.error_ident(); - create_error_type(error_name, &self.segments, None) + create_error_type(&self.route, error_name, &self.segments, None) } } diff --git a/packages/router-macro/src/redirect.rs b/packages/router-macro/src/redirect.rs index 3afefa230..b12f6a910 100644 --- a/packages/router-macro/src/redirect.rs +++ b/packages/router-macro/src/redirect.rs @@ -32,7 +32,7 @@ impl Redirect { pub fn error_type(&self) -> TokenStream { let error_name = self.error_ident(); - create_error_type(error_name, &self.segments, None) + create_error_type(&self.route.value(), error_name, &self.segments, None) } pub fn parse_query(&self) -> TokenStream { diff --git a/packages/router-macro/src/route.rs b/packages/router-macro/src/route.rs index 7244d775c..bf8af74c4 100644 --- a/packages/router-macro/src/route.rs +++ b/packages/router-macro/src/route.rs @@ -338,7 +338,7 @@ impl Route { RouteType::Leaf { .. } => None, }; - create_error_type(error_name, &self.segments, child_type) + create_error_type(&self.route, error_name, &self.segments, child_type) } pub fn parse_query(&self) -> TokenStream2 { diff --git a/packages/router-macro/src/segment.rs b/packages/router-macro/src/segment.rs index 230517afe..eb9db2c48 100644 --- a/packages/router-macro/src/segment.rs +++ b/packages/router-macro/src/segment.rs @@ -1,4 +1,4 @@ -use quote::{format_ident, quote}; +use quote::{format_ident, quote, ToTokens}; use syn::{Ident, Type}; use proc_macro2::{Span, TokenStream as TokenStream2}; @@ -230,6 +230,7 @@ pub fn parse_route_segments<'a>( } pub(crate) fn create_error_type( + route: &str, error_name: Ident, segments: &[RouteSegment], child_type: Option<&Type>, @@ -241,20 +242,42 @@ pub(crate) fn create_error_type( let error_name = segment.error_name(i); match segment { RouteSegment::Static(index) => { - error_variants.push(quote! { #error_name(String) }); + let comment = format!( + " An error that can occur when trying to parse the static segment '/{}'.", + index + ); + error_variants.push(quote! { + #[doc = #comment] + #error_name(String) + }); display_match.push(quote! { Self::#error_name(found) => write!(f, "Static segment '{}' did not match instead found '{}'", #index, found)? }); } RouteSegment::Dynamic(ident, ty) => { let missing_error = segment.missing_error_name().unwrap(); - error_variants.push( - quote! { #error_name(<#ty as dioxus_router::routable::FromRouteSegment>::Err) }, + let comment = format!( + " An error that can occur when trying to parse the dynamic segment '/:{}'.", + ident ); + error_variants.push(quote! { + #[doc = #comment] + #error_name(<#ty as dioxus_router::routable::FromRouteSegment>::Err) + }); display_match.push(quote! { Self::#error_name(err) => write!(f, "Dynamic segment '({}:{})' did not match: {}", stringify!(#ident), stringify!(#ty), err)? }); - error_variants.push(quote! { #missing_error }); + error_variants.push(quote! { + #[doc = #comment] + #missing_error + }); display_match.push(quote! { Self::#missing_error => write!(f, "Dynamic segment '({}:{})' was missing", stringify!(#ident), stringify!(#ty))? }); } RouteSegment::CatchAll(ident, ty) => { - error_variants.push(quote! { #error_name(<#ty as dioxus_router::routable::FromRouteSegments>::Err) }); + let comment = format!( + " An error that can occur when trying to parse the catch-all segment '/:..{}'.", + ident + ); + error_variants.push(quote! { + #[doc = #comment] + #error_name(<#ty as dioxus_router::routable::FromRouteSegments>::Err) + }); display_match.push(quote! { Self::#error_name(err) => write!(f, "Catch-all segment '({}:{})' did not match: {}", stringify!(#ident), stringify!(#ty), err)? }); } } @@ -262,7 +285,14 @@ pub(crate) fn create_error_type( let child_type_variant = child_type .map(|child_type| { - quote! { ChildRoute(<#child_type as std::str::FromStr>::Err) } + let comment = format!( + " An error that can occur when trying to parse the child route [`{}`].", + child_type.to_token_stream() + ); + quote! { + #[doc = #comment] + ChildRoute(<#child_type as std::str::FromStr>::Err) + } }) .into_iter(); @@ -276,10 +306,17 @@ pub(crate) fn create_error_type( }) .into_iter(); + let comment = format!( + " An error that can occur when trying to parse the route variant `{}`.", + route + ); + quote! { + #[doc = #comment] #[allow(non_camel_case_types)] #[allow(clippy::derive_partial_eq_without_eq)] pub enum #error_name { + #[doc = " An error that can occur when extra segments are provided after the route."] ExtraSegments(String), #(#child_type_variant,)* #(#error_variants,)*