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 impls;
23pub(crate) mod utils;
24
25pub(crate) mod ast {
26    #[allow(unused_imports)]
27    pub use self::getter::GetterAst;
28
29    mod getter;
30}
31
32pub(crate) mod attrs {
33    #[doc(inline)]
34    pub use self::prelude::*;
35
36    pub mod display_attrs;
37    pub mod nested;
38    pub mod scsys;
39    pub mod variants;
40
41    pub(crate) mod prelude {
42        pub use super::display_attrs::*;
43        pub use super::nested::*;
44        pub use super::scsys::*;
45        pub use super::variants::*;
46    }
47}
48
49use proc_macro::TokenStream;
50use syn::{Data, DeriveInput, parse_macro_input};
51
52#[proc_macro_derive(Display, attributes(scsys))]
53pub fn display(input: TokenStream) -> TokenStream {
54    // Parse the inputs into the proper struct
55    let ast = parse_macro_input!(input as DeriveInput);
56
57    // Build the impl
58    let res = impls::impl_display(&ast);
59
60    res.into()
61}
62/// This macro automatically generates functional constructors for all enclosed variants.
63#[proc_macro_derive(VariantConstructors, attributes(scsys))]
64pub fn variant_constructors(input: TokenStream) -> TokenStream {
65    let ast: DeriveInput = syn::parse(input).unwrap();
66
67    match ast.data {
68        Data::Enum(inner) => impls::impl_functional_constructors(&ast.ident, &inner.variants),
69        _ => panic!("This derive macro only works with enums"),
70    }
71    .into()
72}
73
74#[proc_macro_derive(Getter)]
75pub fn getter_derive(input: TokenStream) -> TokenStream {
76    let input = parse_macro_input!(input as DeriveInput);
77    impls::impl_getter(&input).into()
78}
79
80#[proc_macro_derive(Set)]
81pub fn set_derive(input: TokenStream) -> TokenStream {
82    let input = parse_macro_input!(input as DeriveInput);
83    impls::impl_set(&input).into()
84}
85
86#[proc_macro_derive(With)]
87pub fn with_derive(input: TokenStream) -> TokenStream {
88    let input = parse_macro_input!(input as DeriveInput);
89    impls::impl_with(&input).into()
90}