Skip to content

Commit 1c6b2da

Browse files
committed
derive: allow where bounds in #[filter_fn]
1 parent 1691d17 commit 1c6b2da

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

askama_derive/src/filter_fn.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use syn::spanned::Spanned;
1212
use syn::token::Mut;
1313
use syn::{
1414
Block, Expr, FnArg, GenericParam, ItemFn, Lifetime, Pat, PatType, ReturnType, Signature, Token,
15-
Type, TypeParamBound, Visibility,
15+
Type, TypeParamBound, Visibility, WhereClause,
1616
};
1717

1818
use crate::{CompileError, HashMap, HashSet, parse_ts_or_compile_error};
@@ -130,6 +130,8 @@ struct FilterSignature {
130130
args_optional: Vec<FilterArgumentOptional>,
131131
/// Generic parameters in use by the required filter arguments
132132
args_required_generics: HashMap<Ident, FilterArgumentGeneric>,
133+
/// The `where` clause of the source function
134+
where_clause: Option<WhereClause>,
133135
/// Filter function result type
134136
result_ty: ReturnType,
135137
}
@@ -272,6 +274,7 @@ impl FilterSignature {
272274
args_required,
273275
args_optional,
274276
args_required_generics,
277+
where_clause: sig.generics.where_clause.clone(),
275278
result_ty: sig.output.clone(),
276279
})
277280
}
@@ -677,6 +680,7 @@ impl FilterSignature {
677680
});
678681

679682
let fn_token = &sig.fn_token;
683+
let where_clause = self.where_clause.as_ref();
680684
let impl_generics = quote! { #(#required_generics: #required_generic_bounds,)* };
681685
let impl_struct_generics = quote! { #(#required_generics,)* #(#required_flags,)* };
682686
let lifetimes_fillers = self.lifetimes_fillers(|l| l.used_by_extra_args);
@@ -690,7 +694,7 @@ impl FilterSignature {
690694
self,
691695
#input_mutability #input_ident: #input_ty,
692696
#env_ident: #env_ty
693-
) #result_ty {
697+
) #result_ty #where_clause {
694698
// map filter variables with original name into scope
695699
#( #required_args )*
696700
#( #optional_args )*

testing/tests/filters.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,3 +717,39 @@ fn filter_lifetimes() {
717717

718718
assert_eq!(X.render().unwrap(), "a-b");
719719
}
720+
721+
// Checks support for `where` clauses.
722+
#[test]
723+
fn issue_671() {
724+
mod filters {
725+
use std::convert::Infallible;
726+
727+
#[askama::filter_fn]
728+
pub fn or_dash<'a, T>(
729+
value: &'a Option<T>,
730+
_: &'a dyn askama::Values,
731+
) -> askama::Result<&'a str, Infallible>
732+
where
733+
T: AsRef<str>,
734+
{
735+
Ok(match value {
736+
Some(value) => value.as_ref(),
737+
None => "--",
738+
})
739+
}
740+
}
741+
742+
#[derive(Template)]
743+
#[template(source = r#"{{ foo | or_dash }}"#, ext = "txt")]
744+
struct Template {
745+
foo: Option<String>,
746+
}
747+
748+
let a = Template { foo: None };
749+
assert_eq!(a.render().unwrap(), "--");
750+
751+
let a = Template {
752+
foo: Some("ok".to_string()),
753+
};
754+
assert_eq!(a.render().unwrap(), "ok");
755+
}

0 commit comments

Comments
 (0)