use std::ops::Index;
use super::Structure;
use super::super::syn::{Body,Variant as SynVariant};
#[derive(Clone,Debug)]
pub struct Variant {
pub name: String,
pub data: Structure
}
impl Variant {
pub fn from_syn_variant(x: &SynVariant) -> Result<Variant,String> {
let name = x.ident.to_string();
let data = match Structure::from_syn_variant(x) {
Ok(x) => x,
Err(e) => return Err(format!("{}\nOn Enum variant {}", e,name))
};
Ok(Variant{
name: name,
data: data
})
}
#[inline(always)]
pub fn get_name<'a>(&'a self) -> &'a str {
&self.name
}
}
#[derive(Clone,Debug)]
pub struct Enumerator(pub Vec<Variant>);
impl Enumerator {
pub fn from_body(x: &Body) -> Result<Enumerator,String> {
match x {
&Body::Struct(_) => Err("Attempted to parse enum but encountered a structure".to_string()),
&Body::Enum(ref x) => {
let mut v = Vec::with_capacity(x.len());
for item in x {
v.push(Variant::from_syn_variant(&item)?);
}
Ok(Enumerator(v))
}
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_discriminant(&self) -> bool {
self.0.iter().fold(true,|x,y|x&&y.data.is_discriminant())
}
pub fn is_unit(&self) -> bool {
self.0.iter().fold(true,|x,y|x&&y.data.is_unit())
}
}
impl Index<usize> for Enumerator {
type Output = Variant;
#[inline(always)]
fn index(&self, x: usize) -> &Self::Output {
self.0.index(x)
}
}