edlcodegen_macros/lib.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! # edlcodegen-macros
5//!
6//! This crate provides the procedural macros used by structs and enums
7//! generated from EDL definitions.
8//!
9//! The macros automatically generates conversion code between the
10//! developer-facing EDL types and their corresponding generated target
11//! representations (e.g., schema-generated types used for serialization
12//! like FlatBuffers).
13//!
14//! - [`#[derive(EdlDerive)]`](EdlDerive) together with
15//! `#[target_struct(path::Type)]` — generates impls for the `core::convert::From` trait
16//! to convert between an EDL-generated struct and its corresponding
17//! target struct type.
18//!
19//! - [`#[derive(EdlDerive)]`](EdlDerive) together with
20//! `#[target_enum(path::Type)]` — generates impls for the `core::convert::From` trait
21//! to convert between an EDL-generated enum and its corresponding
22//! target enum type.
23//!
24//! ## Example
25//! ```ignore
26//! #[derive(EdlDerive)]
27//! #[target_struct(GeneratedModule::NestedStructT)]
28//! pub struct NestedStruct {
29//! pub id: u32,
30//! pub name: String,
31//! pub active: bool,
32//! }
33//!
34//! #[derive(EdlDerive)]
35//! #[target_enum(GeneratedModule::Color)]
36//! pub enum Color {
37//! Red,
38//! Green,
39//! Blue,
40//! }
41//! ```
42
43use proc_macro::TokenStream;
44use syn::parse_macro_input;
45mod derive_enum;
46mod derive_struct;
47mod utils;
48
49/// Entry point for `#[derive(EdlDerive)]`.
50///
51/// Supports:
52/// - `#[target_struct(path::Type)]` — specifies the corresponding target struct.
53/// - `#[target_enum(path::Type)]` — specifies the corresponding target enum.
54/// - `#[boxed_inner_target]` — applied to Generic type fields whose inner type is boxed in the target struct.
55/// - `#[boxed_target]` — applied to fields that are boxed in the target struct.
56///
57/// These annotations guide code generation for automatic conversions between
58/// EDL-defined Rust types and their generated target representations.
59///
60/// Example:
61/// ```ignore
62/// #[derive(EdlDerive)]
63/// #[target_struct(GeneratedModule::FooT)]
64/// pub struct Foo {
65/// #[boxed_inner_target]
66/// pub opt_nested_struct: Option<NestedStruct>,
67///
68/// #[boxed_target]
69/// pub nested_struct: NestedStruct,
70///
71/// pub flag: bool,
72/// }
73/// ```
74#[proc_macro_derive(
75 EdlDerive,
76 attributes(target_struct, target_enum, boxed_inner_target, boxed_target)
77)]
78pub fn edl_type_to_target_type(input: TokenStream) -> TokenStream {
79 let input = parse_macro_input!(input as syn::DeriveInput);
80
81 if let Some(target_path) = utils::find_target_path(&input.attrs, "target_struct") {
82 derive_struct::derive_struct(input, &target_path)
83 } else if let Some(target_path) = utils::find_target_path(&input.attrs, "target_enum") {
84 derive_enum::derive_enum(input, &target_path)
85 } else {
86 panic!("expected #[target_struct(...)] or #[target_enum(...)] attribute");
87 }
88}