liquid_derive/parse_filter/
parse.rs1use super::*;
2
3fn generate_parse_filter(filter_parser: &ParseFilter<'_>) -> Result<TokenStream> {
5 let ParseFilterMeta {
6 parameters_struct_name,
7 filter_struct_name,
8 ..
9 } = &filter_parser.meta;
10
11 let filter_struct_name = filter_struct_name.as_ref().map_err(|err| err.clone())?;
12
13 let impl_parse_filter =
14 filter_parser.generate_impl(quote! { ::liquid_core::parser::ParseFilter });
15
16 if let Some(parameters_struct_name) = parameters_struct_name {
17 let build_filter_parameters = quote_spanned! {parameters_struct_name.span()=>
18 let args = <#parameters_struct_name as ::liquid_core::parser::FilterParameters>::from_args(args)?;
19 };
20
21 let return_expr = quote_spanned! {filter_struct_name.span()=>
22 Ok(::std::boxed::Box::new(<#filter_struct_name as ::std::convert::From<#parameters_struct_name>>::from(args)))
23 };
24
25 Ok(quote! {
26 #impl_parse_filter {
27 fn parse(&self, args: ::liquid_core::parser::FilterArguments) -> ::liquid_core::error::Result<::std::boxed::Box<dyn ::liquid_core::parser::Filter>> {
28 #build_filter_parameters
29 #return_expr
30 }
31
32 fn reflection(&self) -> &dyn ::liquid_core::parser::FilterReflection {
33 self
34 }
35 }
36 })
37 } else {
38 let return_expr = quote_spanned! {filter_struct_name.span()=>
39 #[allow(unknown_lints)]
40 #[allow(clippy::box_default)]
41 ::std::result::Result::Ok(::std::boxed::Box::new(<#filter_struct_name as ::std::default::Default>::default()))
42 };
43 Ok(quote! {
44 #impl_parse_filter {
45 fn parse(&self, mut args: ::liquid_core::parser::FilterArguments) -> ::liquid_core::error::Result<::std::boxed::Box<dyn ::liquid_core::parser::Filter>> {
46 if let ::std::option::Option::Some(arg) = args.positional.next() {
47 return ::std::result::Result::Err(::liquid_core::error::Error::with_msg("Invalid number of positional arguments")
48 .context("cause", concat!("expected at most 0 positional arguments"))
49 );
50 }
51 if let ::std::option::Option::Some(arg) = args.keyword.next() {
52 return ::std::result::Result::Err(::liquid_core::error::Error::with_msg(format!("Unexpected named argument `{}`", arg.0)));
53 }
54
55 #return_expr
56 }
57
58 fn reflection(&self) -> &dyn ::liquid_core::parser::FilterReflection {
59 self
60 }
61 }
62 })
63 }
64}
65
66pub(crate) fn derive(input: &DeriveInput) -> TokenStream {
67 let filter_parser = match ParseFilter::from_input(input) {
68 Ok(filter_parser) => filter_parser,
69 Err(err) => return err.to_compile_error(),
70 };
71
72 match generate_parse_filter(&filter_parser) {
73 Ok(output) => output,
74 Err(err) => err.to_compile_error(),
75 }
76}