aboutsummaryrefslogtreecommitdiff
path: root/macros/src/factory/type_alias.rs
blob: cfa254f95144e1b03129d93e10257d4a94060e87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
use syn::{parse2, ItemType};

use crate::fn_trait::FnTrait;

pub struct FactoryTypeAlias
{
    pub type_alias: ItemType,
    pub factory_interface: FnTrait,
}

impl Parse for FactoryTypeAlias
{
    fn parse(input: ParseStream) -> syn::Result<Self>
    {
        let type_alias = input
            .parse::<ItemType>()
            .map_err(|_| input.error("Expected a type alias"))?;

        let aliased_fn_trait =
            parse2::<FnTrait>(type_alias.ty.as_ref().to_token_stream())?;

        Ok(Self {
            type_alias,
            factory_interface: aliased_fn_trait.clone(),
        })
    }
}

#[cfg(test)]
mod tests
{
    use quote::{format_ident, quote};
    use syn::punctuated::Punctuated;
    use syn::token::And;
    use syn::{Type, TypeReference};

    use super::*;
    use crate::test_utils;

    #[test]
    fn can_parse()
    {
        let input_args = quote! {
            type FooFactory = dyn Fn(String, &u32) -> Foo;
        };

        let factory_type_alias = parse2::<FactoryTypeAlias>(input_args).unwrap();

        assert_eq!(
            factory_type_alias.factory_interface.inputs,
            Punctuated::from_iter(vec![
                test_utils::create_type(test_utils::create_path(&[
                    test_utils::create_path_segment(format_ident!("String"), &[])
                ])),
                Type::Reference(TypeReference {
                    and_token: And::default(),
                    lifetime: None,
                    mutability: None,
                    elem: Box::new(test_utils::create_type(test_utils::create_path(&[
                        test_utils::create_path_segment(format_ident!("u32"), &[])
                    ])))
                })
            ])
        );
    }
}