prosa_macros/
lib.rs

1#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/COPYRIGHT"))]
2//!
3//! [![github]](https://github.com/worldline/ProSA) [![crates-io]](https://crates.io/crates/prosa-macros) [![docs-rs]](crate) [![mdbook]](https://worldline.github.io/ProSA/)
4//!
5#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/doc_assets/header_badges.md"))]
6//!
7//! Base library to defines procedural macros
8
9#![warn(missing_docs)]
10#![deny(unreachable_pub)]
11
12use proc_macro::TokenStream;
13use quote::quote;
14use syn::{Token, parse::Parser, parse_macro_input, punctuated::Punctuated};
15
16mod adaptor;
17mod io;
18mod proc;
19mod settings;
20mod tvf;
21
22fn add_angle_bracketed(
23    name: &str,
24    argument: &mut syn::AngleBracketedGenericArguments,
25) -> syn::parse::Result<()> {
26    for t in argument.args.iter() {
27        if let syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
28            path: syn::Path { segments, .. },
29            ..
30        })) = t
31        {
32            for ps in segments.iter() {
33                if ps.ident == name {
34                    return Ok(());
35                }
36            }
37        }
38    }
39
40    // add the <name> parameter if it's not present
41    let tp: syn::TypePath = syn::parse2(quote! { #name })?;
42    argument
43        .args
44        .push(syn::GenericArgument::Type(syn::Type::Path(tp)));
45
46    Ok(())
47}
48
49/// Derive macro to define a generic ProSA Adaptor.
50#[proc_macro_derive(Adaptor)]
51pub fn adaptor(input: TokenStream) -> TokenStream {
52    adaptor::adaptor_impl(parse_macro_input!(input as syn::DeriveInput))
53        .unwrap_or_else(|e| e.to_compile_error())
54        .into()
55}
56
57/// Procedural macro to help building an ProSA Processor
58#[proc_macro_attribute]
59pub fn proc(args: TokenStream, input: TokenStream) -> TokenStream {
60    let args = match Punctuated::<syn::Meta, Token![,]>::parse_terminated.parse2(args.into()) {
61        Ok(args) => args,
62        Err(e) => return e.to_compile_error().into(),
63    };
64
65    proc::proc_impl(&args, parse_macro_input!(input as syn::Item))
66        .unwrap_or_else(|e| e.to_compile_error())
67        .into()
68}
69
70/// Procedural macro to help building an ProSA Settings
71#[proc_macro_attribute]
72pub fn settings(args: TokenStream, input: TokenStream) -> TokenStream {
73    assert!(args.is_empty());
74    settings::settings_impl(parse_macro_input!(input as syn::Item))
75        .unwrap_or_else(|e| e.to_compile_error())
76        .into()
77}
78
79/// Procedural macro to help building an ProSA Processor Settings
80#[proc_macro_attribute]
81pub fn proc_settings(args: TokenStream, input: TokenStream) -> TokenStream {
82    assert!(args.is_empty());
83    settings::proc_settings_impl(parse_macro_input!(input as syn::Item))
84        .unwrap_or_else(|e| e.to_compile_error())
85        .into()
86}
87
88/// Procedural macro to help defining an ProSA IO (use for socket,...)
89///
90/// ```
91/// struct MyIoClass<IO> {
92///     stream: IO,
93///     buffer: bytes::BytesMut,
94/// }
95/// ```
96#[proc_macro_attribute]
97pub fn io(args: TokenStream, input: TokenStream) -> TokenStream {
98    assert!(args.is_empty());
99    io::io_impl(parse_macro_input!(input as syn::Item))
100        .unwrap_or_else(|e| e.to_compile_error())
101        .into()
102}
103
104/// Macro to generate a TVF message from a JSON-like syntax
105///
106/// ```
107/// use prosa_utils::msg::simple_string_tvf::SimpleStringTvf;
108/// use prosa_macros::tvf;
109///
110/// let message = tvf![ SimpleStringTvf {
111///     1 => 2,
112///     3 => 4usize,
113///     5 => [
114///         "a list starts at index 1",
115///         "support trailing comma",
116///     ],
117///     6 => "2024-01-01" as Date,
118///     7 => "2024-01-01 12:00:00.000" as DateTime,
119///     9 => 0x01020304 as Bytes,
120/// } ];
121/// ```
122#[proc_macro]
123pub fn tvf(input: TokenStream) -> TokenStream {
124    tvf::gen_tvf_impl(input.into())
125        .unwrap_or_else(|e| e.to_compile_error())
126        .into()
127}