use std::collections::HashMap;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Field, Type};
use crate::util::type_add_colon2;
pub trait GetTypeColon2 {
fn get_type_colon2(&self) -> Type;
}
impl GetTypeColon2 for Field {
fn get_type_colon2(&self) -> Type {
let mut ty = self.ty.clone();
type_add_colon2(&mut ty);
ty
}
}
pub trait GetTokenStream {
fn get_token_stream(self) -> TokenStream;
fn get_self_ty() -> TokenStream;
}
macro_rules! impl_get_token_stream {
($ty: ty) => {
impl GetTokenStream for $ty {
fn get_token_stream(self) -> TokenStream {
quote!(#self)
}
fn get_self_ty() -> TokenStream {
quote!($ty)
}
}
};
}
impl_get_token_stream!(bool);
impl_get_token_stream!(u8);
impl_get_token_stream!(u16);
impl_get_token_stream!(u32);
impl_get_token_stream!(usize);
impl_get_token_stream!(u64);
impl_get_token_stream!(u128);
impl_get_token_stream!(i8);
impl_get_token_stream!(i16);
impl_get_token_stream!(i32);
impl_get_token_stream!(i64);
impl_get_token_stream!(i128);
impl_get_token_stream!(f32);
impl_get_token_stream!(f64);
impl_get_token_stream!(&str);
impl<K: GetTokenStream, V: GetTokenStream> GetTokenStream for HashMap<K, V> {
fn get_token_stream(self) -> TokenStream {
if self.is_empty() {
return quote!(HashMap::new());
}
let mut result = quote!();
for (k, v) in self.into_iter() {
let k_token = k.get_token_stream();
let v_token = v.get_token_stream();
result = quote! {
#result
map.insert(#k_token, #v_token);
};
}
quote!({
let mut map = std::collections::HashMap::new();
#result
map
})
}
fn get_self_ty() -> TokenStream {
let k = K::get_self_ty();
let v = V::get_self_ty();
quote!(HashMap::<#k, #v>)
}
}
impl GetTokenStream for String {
fn get_token_stream(self) -> TokenStream {
quote!(#self.into())
}
fn get_self_ty() -> TokenStream {
quote!(String)
}
}
impl<T: GetTokenStream> GetTokenStream for Option<T> {
fn get_token_stream(self) -> TokenStream {
match self {
Some(v) => {
let v_token_stream = v.get_token_stream();
quote!(Some(#v_token_stream))
}
None => quote!(None),
}
}
fn get_self_ty() -> TokenStream {
let t = T::get_self_ty();
quote!(Option::<#t>)
}
}
impl<T: GetTokenStream> GetTokenStream for Vec<T> {
fn get_token_stream(self) -> TokenStream {
let mut items = quote!();
for item in self {
let item_token_stream = item.get_token_stream();
items = quote!(#items #item_token_stream,);
}
quote!(vec![#items])
}
fn get_self_ty() -> TokenStream {
let t = T::get_self_ty();
quote!(Vec::<#t>)
}
}