scsys_derive/
lib.rs

1/*
2    Appellation: scsys-derive <library>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5//! # scsys-derive
6//!
7//! This crate implements the derive macros for the `scsys` ecosystem.
8//!
9//! ## Macros
10//!
11//! - [`Display`]: automatically implements the `Display` trait for a struct or enum, using the
12//!   `scsys` attributes to customize the output.
13//! - [`VariantConstructors`]: generate functional constructors for all variants of an enum
14#![doc(
15    html_logo_url = "https://raw.githubusercontent.com/scattered-systems/.github/main/assets/logo.png",
16    html_favicon_url = "https://raw.githubusercontent.com/scattered-systems/.github/main/assets/favicon.ico"
17)]
18extern crate proc_macro;
19extern crate quote;
20extern crate syn;
21
22pub(crate) mod attrs;
23pub(crate) mod impls;
24pub(crate) mod utils;
25
26pub(crate) mod ast;
27use proc_macro::TokenStream;
28use syn::{Data, DeriveInput, parse_macro_input};
29
30#[proc_macro_derive(Display, attributes(scsys))]
31pub fn display(input: TokenStream) -> TokenStream {
32    // Parse the inputs into the proper struct
33    let ast = parse_macro_input!(input as DeriveInput);
34
35    // Build the impl
36    let res = impls::impl_display(&ast);
37
38    res.into()
39}
40/// This macro automatically generates functional constructors for all enclosed variants.
41#[proc_macro_derive(VariantConstructors, attributes(scsys))]
42pub fn variant_constructors(input: TokenStream) -> TokenStream {
43    let ast: DeriveInput = syn::parse(input).unwrap();
44
45    match ast.data {
46        Data::Enum(inner) => impls::impl_functional_constructors(&ast.ident, &inner.variants),
47        _ => panic!("This derive macro only works with enums"),
48    }
49    .into()
50}
51/// The [`Wrapper`] macro is designed for single-field structs, implementing additional methods
52/// supporting interactions with the inner value
53#[proc_macro_derive(Wrapper, attributes(scsys))]
54pub fn wrapper(input: TokenStream) -> TokenStream {
55    // Parse the inputs into the proper struct
56    let ast = parse_macro_input!(input as DeriveInput);
57
58    // Build the impl
59    let res = impls::impl_wrapper(&ast);
60
61    res.into()
62}
63
64#[proc_macro_derive(Getter, attributes(scsys))]
65pub fn getter_derive(input: TokenStream) -> TokenStream {
66    let input = parse_macro_input!(input as DeriveInput);
67    impls::impl_getter(&input).into()
68}
69
70#[proc_macro_derive(Set, attributes(scsys))]
71pub fn set_derive(input: TokenStream) -> TokenStream {
72    let input = parse_macro_input!(input as DeriveInput);
73    impls::impl_set(&input).into()
74}
75
76#[proc_macro_derive(With, attributes(scsys))]
77pub fn with_derive(input: TokenStream) -> TokenStream {
78    let input = parse_macro_input!(input as DeriveInput);
79    impls::impl_with(&input).into()
80}