use super::FromLiteral;
use super::syn::{
Attribute,
MetaItem,
NestedMetaItem
};
use super::Lit;
macro_rules! is_thing {
($name:ident, $ma: pat) => {
#[inline(always)]
#[allow(dead_code)]
pub fn $name(&self) -> bool {
match self {
$ma => true,
_ => false
}
}
}
}
#[derive(Clone,Debug)]
pub enum HashTag {
Word(String),
List(String,Vec<Box<HashTag>>),
NameValue(String,Lit),
Literal(Lit),
}
fn mapper( x: &NestedMetaItem) -> Box<HashTag> {
let tag = match x {
&NestedMetaItem::Literal(ref x) => HashTag::Literal(x.clone()),
&NestedMetaItem::MetaItem(ref x) => HashTag::new(x),
};
Box::new(tag)
}
impl HashTag {
pub fn new(x: &MetaItem) -> HashTag {
match x {
&MetaItem::Word(ref i) => HashTag::Word(i.to_string()),
&MetaItem::List(ref i,ref arr) => {
let mut v = Vec::with_capacity(arr.len());
for item in arr {
v.push(mapper(&item));
}
HashTag::List(i.to_string(), v)
},
&MetaItem::NameValue(ref i, ref lit) => HashTag::NameValue(i.to_string(), lit.clone())
}
}
pub fn complete(x: &[Attribute]) -> Vec<HashTag> {
let mut v = Vec::with_capacity(x.len());
for item in x {
v.push(HashTag::new(&item.value));
}
v
}
is_thing!(is_word,&HashTag::Word(_));
is_thing!(is_list,&HashTag::List(_,_));
is_thing!(is_name_value,&HashTag::NameValue(_,_));
is_thing!(is_literal,&HashTag::Word(_));
pub fn get_name<'a>(&'a self) -> Option<&'a str> {
match self {
&HashTag::Word(ref w) |
&HashTag::List(ref w, _) |
&HashTag::NameValue(ref w, _) => Some(w),
_ => None
}
}
pub fn get_name_value<'a>(&'a self) -> Option<&'a Lit> {
match self {
&HashTag::NameValue(_, ref l) => Some(l),
_ => None
}
}
pub fn get_arg_list<'a>(&'a self) -> Option<&'a [Box<HashTag>]> {
match self {
&HashTag::List(_,ref l) => Some(l),
_ => None
}
}
pub fn get_literal<'a>(&'a self) -> Option<&'a Lit> {
match self {
&HashTag::Literal(ref l) |
&HashTag::NameValue(_, ref l) => Some(l),
_ => None
}
}
pub fn from_literal(&self) -> Option<FromLiteral> {
match self.get_literal() {
Option::Some(x) => Some(FromLiteral::from(x)),
_ => None
}
}
}