use crate::common;
use quote::{quote, quote_spanned};
use std::collections::HashMap;
#[derive(Clone, Debug, Default)]
pub struct StructDeInfo {
pub token: Option<String>,
pub second_par_check: bool,
pub enum_value: bool,
}
pub fn get_struct_enum_de_info(ast: &syn::DeriveInput) -> (StructDeInfo, proc_macro2::TokenStream) {
let mut struct_info = StructDeInfo::default();
let mut errors = quote! {};
let struct_attrs = get_struct_attrs_variables(ast);
for (key, val) in struct_attrs {
let mut string_quote = "".to_string();
if let Some(val) = val {
if let syn::Lit::Str(string_lit) = val.clone() {
string_quote = string_lit.value();
}
if string_quote.is_empty() {
continue;
}
if string_quote.contains(' ') {
let error = quote_spanned! {
val.span() =>
compile_error!(
"String contains spaces."
);
};
errors = quote! {
#errors
#error
};
}
}
match key.as_ref() {
"token" => struct_info.token = Some(string_quote),
"second_par_check" => struct_info.second_par_check = true,
"enum_value" => struct_info.enum_value = true,
_ => {}
}
}
(struct_info, errors)
}
fn get_struct_attrs_variables(ast: &syn::DeriveInput) -> HashMap<String, Option<syn::Lit>> {
let mut lit_list: HashMap<String, Option<syn::Lit>> = HashMap::new();
for attr in &ast.attrs {
let meta_items = common::get_meta_items(attr, "token_de").unwrap();
for meta_item in meta_items {
match meta_item {
syn::NestedMeta::Meta(syn::Meta::NameValue(m)) if m.path.is_ident("token") => {
lit_list.insert("token".to_owned(), Some(m.lit));
}
syn::NestedMeta::Meta(syn::Meta::Path(m)) if m.is_ident("second_par_check") => {
lit_list.insert("second_par_check".to_owned(), None);
}
syn::NestedMeta::Meta(syn::Meta::Path(m)) if m.is_ident("enum_value") => {
lit_list.insert("enum_value".to_owned(), None);
}
_ => (),
};
}
}
lit_list
}