123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- use proc_macro2::{Ident, TokenStream};
- use quote::{format_ident, quote};
- use syn::LitStr;
- use crate::{
- hash::HashFragment,
- nest::NestId,
- query::QuerySegment,
- segment::{create_error_type, parse_route_segments, RouteSegment},
- };
- #[derive(Debug)]
- pub(crate) struct Redirect {
- pub route: LitStr,
- pub nests: Vec<NestId>,
- pub segments: Vec<RouteSegment>,
- pub query: Option<QuerySegment>,
- pub hash: Option<HashFragment>,
- pub function: syn::ExprClosure,
- pub index: usize,
- }
- impl Redirect {
- pub fn error_ident(&self) -> Ident {
- format_ident!("Redirect{}ParseError", self.index)
- }
- pub fn error_variant(&self) -> Ident {
- format_ident!("Redirect{}", self.index)
- }
- pub fn error_type(&self) -> TokenStream {
- let error_name = self.error_ident();
- create_error_type(error_name, &self.segments, None)
- }
- pub fn parse_query(&self) -> TokenStream {
- match &self.query {
- Some(query) => query.parse(),
- None => quote! {},
- }
- }
- pub fn parse_hash(&self) -> TokenStream {
- match &self.hash {
- Some(hash) => hash.parse(),
- None => quote! {},
- }
- }
- pub fn parse(
- input: syn::parse::ParseStream,
- active_nests: Vec<NestId>,
- index: usize,
- ) -> syn::Result<Self> {
- let path = input.parse::<syn::LitStr>()?;
- let _ = input.parse::<syn::Token![,]>();
- let function = input.parse::<syn::ExprClosure>()?;
- let mut closure_arguments = Vec::new();
- for arg in function.inputs.iter() {
- match arg {
- syn::Pat::Type(pat) => match &*pat.pat {
- syn::Pat::Ident(ident) => {
- closure_arguments.push((ident.ident.clone(), (*pat.ty).clone()));
- }
- _ => {
- return Err(syn::Error::new_spanned(
- arg,
- "Expected closure argument to be a typed pattern",
- ))
- }
- },
- _ => {
- return Err(syn::Error::new_spanned(
- arg,
- "Expected closure argument to be a typed pattern",
- ))
- }
- }
- }
- let (segments, query, hash) = parse_route_segments(
- path.span(),
- #[allow(clippy::map_identity)]
- closure_arguments.iter().map(|(name, ty)| (name, ty)),
- &path.value(),
- )?;
- Ok(Redirect {
- route: path,
- nests: active_nests,
- segments,
- query,
- hash,
- function,
- index,
- })
- }
- }
|