* Add placeholder doc comments to macro-generate enums * Add doc comments to generated router parse error enums --------- Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
103 lines
2.8 KiB
Rust
103 lines
2.8 KiB
Rust
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(&self.route.value(), 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,
|
|
})
|
|
}
|
|
}
|