mlx_internal_macros/
derive_buildable.rs

1use darling::FromDeriveInput;
2use quote::quote;
3use syn::DeriveInput;
4
5use crate::shared::{PathOrIdent, Result};
6
7#[derive(Debug, Clone, FromDeriveInput)]
8#[darling(attributes(buildable))]
9#[allow(dead_code)]
10pub(crate) struct StructProperty {
11    pub ident: syn::Ident,
12
13    /// Generate builder if None
14    pub builder: Option<syn::Path>,
15
16    /// Rename `mlx_rs` if Some(_)
17    pub root: Option<syn::Path>,
18}
19
20pub(crate) fn expand_derive_buildable(input: DeriveInput) -> Result<proc_macro2::TokenStream> {
21    let struct_prop = StructProperty::from_derive_input(&input)?;
22    let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl();
23
24    let struct_ident = &struct_prop.ident;
25    let builder_ident = syn::Ident::new(&format!("{struct_ident}Builder"), struct_ident.span());
26    let root = match struct_prop.root {
27        Some(path) => path,
28        None => syn::parse_quote!(::mlx_rs),
29    };
30
31    let struct_builder_ident = match &struct_prop.builder {
32        Some(path) => PathOrIdent::Path(path.clone()),
33        None => PathOrIdent::Ident(builder_ident),
34    };
35
36    let impl_buildable = quote! {
37        impl #impl_generics #root::builder::Buildable for #struct_ident #type_generics #where_clause {
38            type Builder = #struct_builder_ident #type_generics;
39        }
40    };
41
42    Ok(quote! {
43        #impl_buildable
44    })
45}