cubecl-macros-internal 0.11.0

Internal procedural macros for CubeCL
Documentation
use syn::{
    ExprClosure, Ident, Token, Type,
    parse::{Parse, ParseStream},
    punctuated::Punctuated,
    token,
};

pub struct ConstEval {
    pub op_type: Type,
    _comma: Token![,],
    _brace: token::Brace,
    pub arms: Punctuated<FoldArm, Token![,]>,
}

pub enum FoldArm {
    ConstEval(ConstEvalArm),
    Custom(CustomArm),
}

pub struct ConstEvalArm {
    pub attr_types: TypeList,
    _colon: Token![:],
    pub closure: ExprClosure,
}

pub struct CustomArm {
    _custom: Ident,
    _colon: Token![:],
    pub closure: ExprClosure,
}

pub struct TypeList(pub Punctuated<AttrType, Token![,]>);

pub struct AttrType {
    pub attr_ty: Type,
    pub subtypes: Punctuated<Type, Token![,]>,
}

impl Parse for ConstEval {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let content;
        Ok(ConstEval {
            op_type: input.parse()?,
            _comma: input.parse()?,
            _brace: syn::braced!(content in input),
            arms: content.parse_terminated(FoldArm::parse, Token![,])?,
        })
    }
}

impl Parse for FoldArm {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let fork = input.fork();
        if let Ok(ident) = fork.parse::<Ident>()
            && ident == "custom"
        {
            Ok(FoldArm::Custom(CustomArm::parse(input)?))
        } else {
            Ok(FoldArm::ConstEval(ConstEvalArm::parse(input)?))
        }
    }
}

impl Parse for ConstEvalArm {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        Ok(ConstEvalArm {
            attr_types: input.parse()?,
            _colon: input.parse()?,
            closure: input.parse()?,
        })
    }
}

impl Parse for CustomArm {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        Ok(CustomArm {
            _custom: input.parse()?,
            _colon: input.parse()?,
            closure: input.parse()?,
        })
    }
}

impl Parse for TypeList {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let types = if input.peek(token::Bracket) {
            let content;
            syn::bracketed!(content in input);
            content.parse_terminated(AttrType::parse, Token![,])?
        } else {
            let mut types = Punctuated::new();
            types.push(input.parse()?);
            types
        };
        Ok(Self(types))
    }
}

impl Parse for AttrType {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let attr_ty: Type = input.parse()?;
        let subtypes = if input.peek(token::Paren) {
            let content;
            syn::parenthesized!(content in input);
            content.parse_terminated(Type::parse, Token![,])?
        } else {
            Punctuated::new()
        };
        Ok(Self { attr_ty, subtypes })
    }
}