Skip to main content

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}