procmeta_core/
token.rs

1use std::collections::HashMap;
2
3use proc_macro2::TokenStream;
4use quote::quote;
5use syn::{Field, Type};
6
7use crate::util::type_add_colon2;
8
9pub trait GetTypeColon2 {
10    fn get_type_colon2(&self) -> Type;
11}
12
13impl GetTypeColon2 for Field {
14    fn get_type_colon2(&self) -> Type {
15        let mut ty = self.ty.clone();
16        type_add_colon2(&mut ty);
17        ty
18    }
19}
20
21pub trait GetTokenStream {
22    fn get_token_stream(self) -> TokenStream;
23
24    fn get_self_ty() -> TokenStream;
25}
26
27macro_rules! impl_get_token_stream {
28    ($ty: ty) => {
29        impl GetTokenStream for $ty {
30            fn get_token_stream(self) -> TokenStream {
31                quote!(#self)
32            }
33
34            fn get_self_ty() -> TokenStream {
35                quote!($ty)
36            }
37        }
38    };
39}
40
41impl_get_token_stream!(bool);
42impl_get_token_stream!(u8);
43impl_get_token_stream!(u16);
44impl_get_token_stream!(u32);
45impl_get_token_stream!(usize);
46impl_get_token_stream!(u64);
47impl_get_token_stream!(u128);
48impl_get_token_stream!(i8);
49impl_get_token_stream!(i16);
50impl_get_token_stream!(i32);
51impl_get_token_stream!(i64);
52impl_get_token_stream!(i128);
53impl_get_token_stream!(f32);
54impl_get_token_stream!(f64);
55impl_get_token_stream!(&str);
56
57impl<K: GetTokenStream, V: GetTokenStream> GetTokenStream for HashMap<K, V> {
58    fn get_token_stream(self) -> TokenStream {
59        if self.is_empty() {
60            return quote!(HashMap::new());
61        }
62        let mut result = quote!();
63        for (k, v) in self.into_iter() {
64            let k_token = k.get_token_stream();
65            let v_token = v.get_token_stream();
66            result = quote! {
67                #result
68                map.insert(#k_token, #v_token);
69            };
70        }
71        quote!({
72            let mut map = std::collections::HashMap::new();
73            #result
74            map
75        })
76    }
77
78    fn get_self_ty() -> TokenStream {
79        let k = K::get_self_ty();
80        let v = V::get_self_ty();
81        quote!(HashMap::<#k, #v>)
82    }
83}
84
85impl GetTokenStream for String {
86    fn get_token_stream(self) -> TokenStream {
87        quote!(#self.into())
88    }
89
90    fn get_self_ty() -> TokenStream {
91        quote!(String)
92    }
93}
94
95impl<T: GetTokenStream> GetTokenStream for Option<T> {
96    fn get_token_stream(self) -> TokenStream {
97        match self {
98            Some(v) => {
99                let v_token_stream = v.get_token_stream();
100                quote!(Some(#v_token_stream))
101            }
102            None => quote!(None),
103        }
104    }
105
106    fn get_self_ty() -> TokenStream {
107        let t = T::get_self_ty();
108        quote!(Option::<#t>)
109    }
110}
111
112impl<T: GetTokenStream> GetTokenStream for Vec<T> {
113    fn get_token_stream(self) -> TokenStream {
114        let mut items = quote!();
115        for item in self {
116            let item_token_stream = item.get_token_stream();
117            items = quote!(#items #item_token_stream,);
118        }
119        quote!(vec![#items])
120    }
121
122    fn get_self_ty() -> TokenStream {
123        let t = T::get_self_ty();
124        quote!(Vec::<#t>)
125    }
126}