use crate::common;
use quote::{quote, quote_spanned};
use std::collections::HashMap;
#[derive(Clone, Debug, Default)]
pub struct TokenDeInfo {
pub token: Option<String>,
pub on_duplicate_to_parent: bool,
pub on_duplicate_error: bool,
pub primary_token: bool,
pub alias: Option<String>, }
pub fn get_token_de_info(field: &syn::Field) -> (TokenDeInfo, proc_macro2::TokenStream) {
let mut token_info = TokenDeInfo::default();
let mut errors = quote! {};
for (_i, attr) in field.attrs.iter().enumerate() {
let token_attrs = get_token_attrs_variables(attr);
for (key, val) in token_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" => token_info.token = Some(string_quote),
"on_duplicate_to_parent" => token_info.on_duplicate_to_parent = true,
"on_duplicate_error" => token_info.on_duplicate_error = true,
"primary_token" => token_info.primary_token = true,
"alias" => token_info.alias = Some(string_quote),
_ => {}
}
}
}
(token_info, errors)
}
fn get_token_attrs_variables(attr: &syn::Attribute) -> HashMap<String, Option<syn::Lit>> {
let meta_items = common::get_meta_items(attr, "token_de").unwrap();
let mut lit_list: HashMap<String, Option<syn::Lit>> = HashMap::new();
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("on_duplicate_to_parent") => {
lit_list.insert("on_duplicate_to_parent".to_owned(), None);
}
syn::NestedMeta::Meta(syn::Meta::Path(m)) if m.is_ident("on_duplicate_error") => {
lit_list.insert("on_duplicate_error".to_owned(), None);
}
syn::NestedMeta::Meta(syn::Meta::Path(m)) if m.is_ident("primary_token") => {
lit_list.insert("primary_token".to_owned(), None);
}
syn::NestedMeta::Meta(syn::Meta::NameValue(m)) if m.path.is_ident("alias") => {
lit_list.insert("alias".to_owned(), Some(m.lit));
}
_ => (),
};
}
lit_list
}