default_conversion/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::Ident;
4use syn::{parse_macro_input, DeriveInput};
5
6fn _print_type_of<T>(_: &T) {
7 println!("{}", std::any::type_name::<T>())
8}
9
10#[proc_macro_derive(IntoDefault, attributes(IntoStruct, IntoType))]
11pub fn into_default(item: TokenStream) -> TokenStream {
12 let ast = parse_macro_input!(item as DeriveInput);
13 let attributes = &ast.attrs;
14 let base_type = &ast.ident;
15 let mut code: TokenStream = TokenStream::from(quote! {});
16 for attribute in attributes {
17 if attribute.path.is_ident("IntoStruct") {
18 let type_struct = attribute.parse_args::<Ident>().unwrap();
19 if let syn::Data::Struct(d) = &ast.data {
20 if let syn::Fields::Named(f) = &d.fields {
21 let fields = &f.named;
22 let mut fields_name = Vec::new();
23 let mut fields_value = Vec::new();
24 for field in fields {
25 let type_temp = &field.ident;
26 let mut quote_temp = quote! {item.#type_temp.into()};
27 fields_name.push(&field.ident);
28 if let syn::Type::Path(path) = &field.ty {
29 for segment in &path.path.segments {
30 if segment.ident == "Option" {
31 quote_temp = quote! {match item.#type_temp {
32 Some(value) => value.into(),
33 None => Default::default()
34 }};
35 } else if segment.ident == "Vec" {
36 quote_temp = quote! {item.#type_temp.into_iter().map(|v| v.into()).collect::<Vec<_>>()};
37 }
38 }
39 }
40 fields_value.push(quote_temp);
41 }
42 code = TokenStream::from(quote! {
43 impl From<Option<#base_type>> for #type_struct {
44 fn from(item: Option<#base_type>) -> Self {
45 match item {
46 Some(v) => v.into(),
47 None => Default::default()
48 }
49 }
50 }
51
52 impl Into<Option<#type_struct>> for #base_type {
53 fn into(self) -> Option<#type_struct> {
54 Some(self.into())
55 }
56 }
57
58 impl Into<Vec<#type_struct>> for #base_type {
59 fn into(self) -> Vec<#type_struct> {
60 vec! {self.into()}
61 }
62 }
63
64 impl From<#base_type> for #type_struct {
65 fn from(item: #base_type) -> Self {
66 #type_struct {
67 #(#fields_name: #fields_value ,)*
68 }
69 }
70 }
71
72 });
73 }
74 }
75 } else {
76 TokenStream::from(quote! {});
77 }
78 }
79 code
80}