codgenhelp 0.0.1

Simplifies structure and enum parsing in Macros1.1
Documentation
//! Macrohelper
//!
//! This crate's goal of this crate is to make you not want to tear your hair out when working with
//! `syn` crate for Macro's1.1
//!
//! Some core enums from `syn` are re-exported that represent core types

#![feature(proc_macro, proc_macro_lib)]
extern crate proc_macro;
pub use proc_macro::TokenStream;

extern crate syn;
#[allow(unused_imports)]
pub use syn::{
    Lit,
    StrStyle,
    IntTy,
    FloatTy,
    Ty,
    Lifetime,
    ConstExpr
};
pub mod meta;
#[allow(unused_imports)]
pub use meta::HashTag;
pub mod bodykind;
#[allow(unused_imports)]
use bodykind::{
    BodyKind,
    Enumerator,
    Variant,
    Field,
    Fields,
    Structure
};

macro_rules! is_thing {
    ($name:ident, $ma: pat) => {
        #[inline(always)]
        #[allow(dead_code)]
        pub fn $name(&self) -> bool {
            match self {
                $ma => true,
                _ => false
            }
        }
    }
}

/// Input to a macro1.1 invocation
///
/// Macro1.1 compiler hook gives a string of tokens. That is converted to an AST by `syn`.
/// This crate then converts `syn`'s output into this type.
#[derive(Clone,Debug)]
#[allow(dead_code)]
pub struct MacroInput {
    /// Information about any and all `#[...]` headers
    pub attr: Vec<HashTag>,
    /// Name of the structure or enum
    pub id: String,
    /// Informatin about the body
    pub body: BodyKind
}
impl MacroInput {
    /// High level fake implemenation.
    ///
    /// Just converts `TokenStream` to a string, and called `from_str`
    pub fn from_tree(input: TokenStream) -> Result<MacroInput,String> {
        let s = input.to_string();
        MacroInput::from_str(&s)
    }
    /// Actual implementation of the conversion
    #[inline]
    pub fn from_str(s: &str) -> Result<MacroInput,String> {
        use std::mem;

        //parse the input
        let ast = syn::parse_macro_input(s)?;

        //build the return value
        let mut ret_val: MacroInput = unsafe{ mem::uninitialized() };
        ret_val.id = ast.ident.to_string();
        ret_val.attr = HashTag::complete( &ast.attrs);

        //return value
        Ok(ret_val)
    }
}
/// Derive traits for tests
///
/// Even tho `syn` has `PartialEq` and `Eq` derived for most types I'm getting massive
///
#[derive(Clone,Debug,PartialEq,Eq)]
pub enum FromLiteral {
    Str(String),
    ByteStr(Vec<u8>),
    Byte(u8),
    Int(u64),
    Float(String),
    Bool(bool),
    Char(char)
}
impl From<Lit> for FromLiteral {
    fn from(x: Lit) -> FromLiteral {
        match x {
            Lit::Str(w,_) => FromLiteral::Str(w),
            Lit::ByteStr(w,_) => FromLiteral::ByteStr(w),
            Lit::Byte(w) => FromLiteral::Byte(w),
            Lit::Int(w,_) => FromLiteral::Int(w),
            Lit::Char(w) => FromLiteral::Char(w),
            Lit::Bool(w) => FromLiteral::Bool(w),
            Lit::Float(w,_) => FromLiteral::Float(w)
        }
    }
}
impl<'a> From<&'a Lit> for FromLiteral {
    fn from(x: &'a Lit) -> FromLiteral {
        match x {
            &Lit::Str(ref w,_) => FromLiteral::Str(w.clone()),
            &Lit::ByteStr(ref w,_) => FromLiteral::ByteStr(w.clone()),
            &Lit::Byte(ref w) => FromLiteral::Byte(w.clone()),
            &Lit::Int(ref w,_) => FromLiteral::Int(w.clone()),
            &Lit::Char(ref w) => FromLiteral::Char(w.clone()),
            &Lit::Bool(ref w) => FromLiteral::Bool(w.clone()),
            &Lit::Float(ref w,_) => FromLiteral::Float(w.clone())
        }
    }
}
impl FromLiteral {
    is_thing!(is_str,&FromLiteral::Str(_));
    is_thing!(is_bytestr,&FromLiteral::ByteStr(_));
    is_thing!(is_byte,&FromLiteral::Byte(_));
    is_thing!(is_int,&FromLiteral::Int(_));
    is_thing!(is_float,&FromLiteral::Float(_));
    is_thing!(is_bool,&FromLiteral::Bool(_));
    is_thing!(is_char,&FromLiteral::Char(_));
}