gdrust_macros 0.1.0

You are probably looking for `gdrust`. This is the macros it exports.
Documentation
use proc_macro2::Ident;
use syn::parse::{Parse, ParseStream, Result};
use syn::parse_macro_input::parse;
use syn::punctuated::Punctuated;
use syn::{parenthesized, token, Expr, Field, ItemStruct, Lit, LitStr, Token, Type};

mod kw {
    syn::custom_keyword!(export);
    syn::custom_keyword!(or_greater);
    syn::custom_keyword!(or_lesser);
    syn::custom_keyword!(var);
    syn::custom_keyword!(no_export);
    syn::custom_keyword!(export_range);
    syn::custom_keyword!(export_enum);
    syn::custom_keyword!(export_file);
    syn::custom_keyword!(export_dir);
    syn::custom_keyword!(export_global_file);
    syn::custom_keyword!(export_global_dir);
    syn::custom_keyword!(export_multiline);
    syn::custom_keyword!(export_exp_range);
    syn::custom_keyword!(export_color_no_alpha);
    syn::custom_keyword!(export_node_path);
    syn::custom_keyword!(export_flags);
    syn::custom_keyword!(export_flags_2d_physics);
    syn::custom_keyword!(export_flags_2d_render);
    syn::custom_keyword!(export_flags_3d_physics);
    syn::custom_keyword!(export_flags_3d_render);
}

#[derive(Clone)]
pub enum ExportType {
    NoHint,
    NoExport,
    Export,
    ExportRange(ExportRange),
    ExportExpRange(ExportExpRange),
    ExportEnum(ExportEnum),
    ExportFile(ExportFile),
    ExportDir,
    ExportGlobalFile(ExportGlobalFile),
    ExportGlobalDir,
    ExportMultiline,
    ExportColorNoAlpha,
    ExportNodePath(ExportNodePath),
    ExportFlags(ExportFlags),
    ExportFlags2dPhysics,
    ExportFlags2dRender,
    ExportFlags3dPhysics,
    ExportFlags3dRender,
}

#[derive(Clone)]
pub struct ExportRange {
    pub paren_token: token::Paren,
    pub range: Punctuated<Lit, Token![,]>,
}

impl Parse for ExportRange {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        let paren_token = parenthesized!(content in input);
        let range = content.parse_terminated(Lit::parse)?;
        Ok(Self { paren_token, range })
    }
}

#[derive(Clone)]
pub struct ExportExpRange {
    pub paren_token: token::Paren,
    pub range: Punctuated<Lit, Token![,]>,
}

impl Parse for ExportExpRange {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        let paren_token = parenthesized!(content in input);
        let range = content.parse_terminated(Lit::parse)?;
        Ok(Self { paren_token, range })
    }
}

#[derive(Clone)]
pub struct ExportEnum {
    pub paren_token: token::Paren,
    pub values: Punctuated<LitStr, Token![,]>,
}

impl Parse for ExportEnum {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        let paren_token = parenthesized!(content in input);
        let values = content.parse_terminated(<LitStr as Parse>::parse)?;
        Ok(Self {
            paren_token,
            values,
        })
    }
}

#[derive(Clone)]
pub struct ExportFile {
    pub filter: Option<(token::Paren, LitStr)>,
}

impl Parse for ExportFile {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Self {
            filter: if input.peek(token::Paren) {
                let content;
                let paren = parenthesized!(content in input);
                let filter = content.parse()?;
                Some((paren, filter))
            } else {
                None
            },
        })
    }
}

#[derive(Clone)]
pub struct ExportGlobalFile {
    pub filter: Option<(token::Paren, LitStr)>,
}

impl Parse for ExportGlobalFile {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Self {
            filter: if input.peek(token::Paren) {
                let content;
                let paren = parenthesized!(content in input);
                let filter = content.parse()?;
                Some((paren, filter))
            } else {
                None
            },
        })
    }
}

#[derive(Clone)]
pub struct ExportMultiline {
    pub export_multiline: kw::export_multiline,
}

#[derive(Clone)]
pub struct ExportColorNoAlpha {
    pub export_color_no_alpha: kw::export_color_no_alpha,
}

#[derive(Clone)]
pub struct ExportNodePath {
    pub types: Option<(token::Paren, Punctuated<Type, Token![,]>)>,
}

impl Parse for ExportNodePath {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Self {
            types: if input.peek(token::Paren) {
                let content;
                let paren = parenthesized!(content in input);
                let types = content.parse_terminated(Type::parse)?;
                Some((paren, types))
            } else {
                None
            },
        })
    }
}

#[derive(Clone)]
pub struct ExportFlags {
    pub paren_token: token::Paren,
    pub values: Punctuated<LitStr, Token![,]>,
}

impl Parse for ExportFlags {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        let paren_token = parenthesized!(content in input);
        let values = content.parse_terminated(<LitStr as Parse>::parse)?;
        Ok(Self {
            paren_token,
            values,
        })
    }
}

pub struct Property {
    pub name: Ident,
    pub ty: Type,
    pub export_type: ExportType,
    pub default: Option<Expr>,
}

impl Property {
    fn new(name: Ident, ty: Type) -> Self {
        Self {
            name,
            ty,
            export_type: ExportType::NoHint,
            default: None,
        }
    }
}

struct DefaultProperty {
    pub paren_token: token::Paren,
    pub expr: Expr,
}

impl Parse for DefaultProperty {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        let paren_token = parenthesized!(content in input);
        let expr = content.parse()?;
        Ok(Self { paren_token, expr })
    }
}

#[allow(clippy::module_name_repetitions)]
pub fn extract_properties(item: &mut ItemStruct) -> Vec<Property> {
    item.fields.iter_mut().map(|x| get_property(x)).collect()
}

pub fn get_property(item: &mut Field) -> Property {
    let mut property = Property::new(
        item.ident
            .as_ref()
            .expect("Properties must be on named field")
            .clone(),
        item.ty.clone(),
    );
    item.attrs = item
        .attrs
        .iter()
        .filter(|x| {
            let ident = x
                .path
                .get_ident()
                .expect("Expected valid attr on property")
                .to_string();
            let mut should_filter = false;
            let tokens = x.tokens.clone().into();
            match ident.as_str() {
                "default" => {
                    let default = parse::<DefaultProperty>(tokens)
                        .expect("Invalid params for default")
                        .expr;
                    property.default = Some(default);
                }
                "export" => property.export_type = ExportType::Export,
                "no_export" => property.export_type = ExportType::NoExport,
                "export_range" => {
                    let range = parse(tokens).expect("Invalid range on export_range");
                    property.export_type = ExportType::ExportRange(range);
                }
                "export_enum" => {
                    let export_enum = parse::<ExportEnum>(tokens).expect("Invalid exportenum");
                    property.export_type = ExportType::ExportEnum(export_enum);
                }
                "export_file" => {
                    let export_file = parse(tokens).expect("Invalid export_file");
                    property.export_type = ExportType::ExportFile(export_file)
                }
                "export_dir" => property.export_type = ExportType::ExportDir,
                "export_global_file" => {
                    let export_global_file = parse(tokens).expect("Invalid export_file");
                    property.export_type = ExportType::ExportGlobalFile(export_global_file)
                }
                "export_global_dir" => property.export_type = ExportType::ExportGlobalDir,
                "export_multiline" => property.export_type = ExportType::ExportMultiline,
                "export_exp_range" => {
                    let range = parse(tokens).expect("Invalid range on export_exp_range");
                    property.export_type = ExportType::ExportExpRange(range);
                }
                "export_color_no_alpha" => property.export_type = ExportType::ExportColorNoAlpha,
                "export_flags" => {
                    let flags = parse(tokens).expect("Invalid export_flags");
                    property.export_type = ExportType::ExportFlags(flags)
                }
                "export_node_path" => {
                    let types = parse(tokens).expect("Invalid args for export_node_path");
                    property.export_type = ExportType::ExportNodePath(types)
                }
                "export_flags_2d_physics" => {
                    property.export_type = ExportType::ExportFlags2dPhysics
                }
                "export_flags_2d_render" => property.export_type = ExportType::ExportFlags2dRender,
                "export_flags_3d_physics" => {
                    property.export_type = ExportType::ExportFlags3dPhysics
                }
                "export_flags_3d_render" => property.export_type = ExportType::ExportFlags3dRender,
                _ => should_filter = true,
            }
            should_filter
        })
        .cloned()
        .collect();
    property
}