crossflow_derive/
lib.rs

1/*
2 * Copyright (C) 2024 Open Source Robotics Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16*/
17
18mod derive_buffer;
19use derive_buffer::{impl_buffer_key_map, impl_joined_value};
20
21mod derive_section;
22use derive_section::impl_section;
23
24mod derive_stream;
25use derive_stream::impl_derive_stream;
26
27mod derive_stream_pack;
28use derive_stream_pack::impl_stream_pack;
29
30use proc_macro::TokenStream;
31use quote::quote;
32use syn::{DeriveInput, ItemStruct, parse_macro_input};
33
34#[proc_macro_derive(Stream)]
35pub fn derive_stream(item: TokenStream) -> TokenStream {
36    let input = parse_macro_input!(item as ItemStruct);
37    match impl_derive_stream(&input) {
38        Ok(tokens) => tokens.into(),
39        Err(msg) => quote! {
40            compile_error!(#msg);
41        }
42        .into(),
43    }
44}
45
46#[proc_macro_derive(DeliveryLabel)]
47pub fn delivery_label_macro(item: TokenStream) -> TokenStream {
48    let ast: DeriveInput = syn::parse(item).unwrap();
49    let struct_name = &ast.ident;
50    let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
51
52    quote! {
53        impl #impl_generics ::crossflow::DeliveryLabel for #struct_name #type_generics #where_clause {
54            fn dyn_debug(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
55                ::std::fmt::Debug::fmt(self, f)
56            }
57
58            fn as_dyn_eq(&self) -> &dyn ::crossflow::service_utils::DynEq {
59                self
60            }
61
62            fn dyn_hash(&self, mut state: &mut dyn ::std::hash::Hasher) {
63                let ty_id = ::std::any::TypeId::of::<Self>();
64                ::std::hash::Hash::hash(&ty_id, &mut state);
65                ::std::hash::Hash::hash(self, &mut state);
66            }
67        }
68    }
69    .into()
70}
71
72/// The result error is the compiler error message to be displayed.
73type Result<T> = std::result::Result<T, String>;
74
75#[proc_macro_derive(Joined, attributes(joined))]
76pub fn derive_joined_value(input: TokenStream) -> TokenStream {
77    let input = parse_macro_input!(input as ItemStruct);
78    match impl_joined_value(&input) {
79        Ok(tokens) => tokens.into(),
80        Err(msg) => quote! {
81            compile_error!(#msg);
82        }
83        .into(),
84    }
85}
86
87#[proc_macro_derive(Accessor, attributes(key))]
88pub fn derive_buffer_key_map(input: TokenStream) -> TokenStream {
89    let input = parse_macro_input!(input as ItemStruct);
90    match impl_buffer_key_map(&input) {
91        Ok(tokens) => tokens.into(),
92        Err(msg) => quote! {
93            compile_error!(#msg);
94        }
95        .into(),
96    }
97}
98
99#[proc_macro_derive(Section, attributes(message))]
100pub fn derive_section(input: TokenStream) -> TokenStream {
101    let input = parse_macro_input!(input as ItemStruct);
102    match impl_section(&input) {
103        Ok(tokens) => tokens.into(),
104        Err(msg) => quote! {
105            compile_error!(#msg);
106        }
107        .into(),
108    }
109}
110
111#[proc_macro_derive(StreamPack, attributes(stream))]
112pub fn derive_stream_pack(input: TokenStream) -> TokenStream {
113    let input = parse_macro_input!(input as ItemStruct);
114    match impl_stream_pack(&input) {
115        Ok(ok) => ok.into(),
116        Err(msg) => quote! {
117            compile_error!(#msg);
118        }
119        .into(),
120    }
121}