diff options
author | HampusM <hampus@hampusmat.com> | 2022-09-12 20:22:13 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-09-17 14:33:15 +0200 |
commit | c1e682c25c24be3174d44ceb95b0537c38299d0c (patch) | |
tree | 6e59f37e1b98e68fad2e3e2fe4a428ac97fcf8b4 /macros/src/fn_trait.rs | |
parent | e8e48906a3899e71c9c9d86a3d4528cb7d17e5b9 (diff) |
feat!: allow factories access to DI container
BREAKING CHANGE: Factory types should now be written with the Fn trait instead of the IFactory trait and the to_factory & to_default_factory methods of BindingBuilder now expect a function returning a factory function
Diffstat (limited to 'macros/src/fn_trait.rs')
-rw-r--r-- | macros/src/fn_trait.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/macros/src/fn_trait.rs b/macros/src/fn_trait.rs new file mode 100644 index 0000000..f9b3514 --- /dev/null +++ b/macros/src/fn_trait.rs @@ -0,0 +1,68 @@ +use quote::ToTokens; +use syn::parse::Parse; +use syn::punctuated::Punctuated; +use syn::token::Paren; +use syn::{parenthesized, Ident, Token, Type}; + +/// A function trait. `dyn Fn(u32) -> String` +#[derive(Debug, Clone)] +pub struct FnTrait +{ + pub dyn_token: Token![dyn], + pub trait_ident: Ident, + pub paren_token: Paren, + pub inputs: Punctuated<Type, Token![,]>, + pub r_arrow_token: Token![->], + pub output: Type, +} + +impl Parse for FnTrait +{ + fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> + { + let dyn_token = input.parse::<Token![dyn]>()?; + + let trait_ident = input.parse::<Ident>()?; + + if trait_ident.to_string().as_str() != "Fn" { + return Err(syn::Error::new(trait_ident.span(), "Expected 'Fn'")); + } + + let content; + + let paren_token = parenthesized!(content in input); + + let inputs = content.parse_terminated(Type::parse)?; + + let r_arrow_token = input.parse::<Token![->]>()?; + + let output = input.parse::<Type>()?; + + Ok(Self { + dyn_token, + trait_ident, + paren_token, + inputs, + r_arrow_token, + output, + }) + } +} + +impl ToTokens for FnTrait +{ + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) + { + self.dyn_token.to_tokens(tokens); + + self.trait_ident.to_tokens(tokens); + + self.paren_token.surround(tokens, |tokens_inner| { + self.inputs.to_tokens(tokens_inner); + }); + + self.r_arrow_token.to_tokens(tokens); + + self.output.to_tokens(tokens); + } +} |