use super::{Fields};
use super::super::{Lit,FromLiteral};
use super::super::syn::{VariantData,ConstExpr,Variant as SynVariant, Body};
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 Structure {
NormalStruct(Fields),
TupleStruct(Fields),
Unit,
Discriminant(Lit)
}
impl Structure {
pub fn from_syn_variant(x: &SynVariant) -> Result<Structure,String> {
match &x.discriminant {
&Option::None => { },
&Option::Some(ConstExpr::Lit(ref x)) => return Ok(Structure::Discriminant(x.clone())),
&Option::Some(_) => return Err("Encountered `Variant` who's discriminant existed BUT that value wasn't a literal".to_string())
};
Ok(Structure::from_variantdata(&x.data))
}
#[inline(always)]
pub fn from_variantdata(x: &VariantData) -> Structure {
match x {
&VariantData::Unit => Structure::Unit,
&VariantData::Tuple(ref f) => Structure::TupleStruct(Fields::from(f)),
&VariantData::Struct(ref f) => Structure::NormalStruct(Fields::from(f))
}
}
pub fn from_body(x: &Body) -> Result<Structure,String> {
match x {
&Body::Enum(_) => Err("Attempted to parse struct but encountered a enum".to_string()),
&Body::Struct(ref x) => Ok(Structure::from_variantdata(x))
}
}
is_thing!(is_unit,&Structure::Unit);
is_thing!(is_norm,&Structure::NormalStruct(_));
is_thing!(is_tuple,&Structure::TupleStruct(_));
is_thing!(is_discriminant,&Structure::Discriminant(_));
pub fn get_fields<'a>(&'a self) -> Option<&'a Fields> {
match self {
&Structure::NormalStruct(ref f) |
&Structure::TupleStruct(ref f) => Some(f),
_ => None
}
}
pub fn get_literal<'a>(&'a self) -> Option<&'a Lit> {
match self {
&Structure::Discriminant(ref l) => Some(l),
_ => None
}
}
pub fn from_literal(&self) -> Option<FromLiteral> {
match self.get_literal() {
Option::Some(x) => Some(FromLiteral::from(x)),
_ => None
}
}
}