codgenhelp 0.0.1

Simplifies structure and enum parsing in Macros1.1
Documentation
use std::ops::Index;
use super::Structure;
use super::super::syn::{Body,Variant as SynVariant};


/// Representation of an Enum
///
/// Enum's are really just a union (shared memory) while what is stored in that type
/// is really just a question of what variation of that data the enum currently is.
///
/// Therefore this just stores a name, and a reference to the structure
#[derive(Clone,Debug)]
pub struct Variant {
    pub name: String,
    pub data: Structure
}
impl Variant {

    /// Build from `syn`'s Variant type
    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
        })
    }
    /// Eaiser to get name
    #[inline(always)]
    pub fn get_name<'a>(&'a self) -> &'a str {
        &self.name
    }
}

/// The collect of all types an Enum can be.
#[derive(Clone,Debug)]
pub struct Enumerator(pub Vec<Variant>);
impl Enumerator {

    /// Constructs an enumerator from a Body
    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))
            }
        }
    }
    /// Get number of args
    #[inline(always)]
    pub fn len(&self) -> usize {
        self.0.len()
    }
    /// Are all fields just flat values
    pub fn is_discriminant(&self) -> bool {
        self.0.iter().fold(true,|x,y|x&&y.data.is_discriminant())
    }
    /// Are all fields zero sized
    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)
    }
}