123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- use proc_macro2::TokenStream;
- use quote::{format_ident, quote};
- use syn::{Ident, LitStr};
- use crate::segment::{create_error_type, parse_route_segments, RouteSegment};
- #[derive(Debug, Clone, Copy)]
- pub struct NestId(pub usize);
- #[derive(Debug, Clone)]
- pub struct Nest {
- pub route: String,
- pub segments: Vec<RouteSegment>,
- index: usize,
- }
- impl Nest {
- pub fn parse(
- input: syn::parse::ParseStream,
- children_routes: Vec<syn::FieldsNamed>,
- index: usize,
- ) -> syn::Result<Self> {
- // Parse the route
- let route: LitStr = input.parse()?;
- let route_segments = parse_route_segments(
- route.span(),
- children_routes
- .iter()
- .flat_map(|f| f.named.iter())
- .map(|f| (f.ident.as_ref().unwrap(), &f.ty)),
- &route.value(),
- )?
- .0;
- for seg in &route_segments {
- if let RouteSegment::CatchAll(name, _) = seg {
- return Err(syn::Error::new_spanned(
- name,
- format!(
- "Catch-all segments are not allowed in nested routes: {}",
- route.value()
- ),
- ));
- }
- }
- Ok(Self {
- route: route.value(),
- segments: route_segments,
- index,
- })
- }
- }
- impl Nest {
- pub fn dynamic_segments(&self) -> impl Iterator<Item = TokenStream> + '_ {
- self.dynamic_segments_names().map(|i| quote! {#i})
- }
- pub fn dynamic_segments_names(&self) -> impl Iterator<Item = Ident> + '_ {
- self.segments.iter().filter_map(|seg| seg.name())
- }
- pub fn write(&self) -> TokenStream {
- let write_segments = self.segments.iter().map(|s| s.write_segment());
- quote! {
- {
- #(#write_segments)*
- }
- }
- }
- pub fn error_ident(&self) -> Ident {
- format_ident!("Nest{}ParseError", self.index)
- }
- pub fn error_variant(&self) -> Ident {
- format_ident!("Nest{}", self.index)
- }
- pub fn error_type(&self) -> TokenStream {
- let error_name = self.error_ident();
- create_error_type(&self.route, error_name, &self.segments, None)
- }
- }
|