sigstore_protobuf_specs_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput};
4
5#[proc_macro_derive(Serialize_proto)]
6pub fn derive_serialize(input: TokenStream) -> TokenStream {
7    let input = parse_macro_input!(input as DeriveInput);
8    let ident = input.ident;
9
10    match input.data {
11        syn::Data::Struct(_) => (),
12        _ => return Default::default(),
13    };
14
15    let expanded = quote! {
16        impl serde::Serialize for #ident {
17            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
18            where
19                S: serde::Serializer,
20            {
21                let message = prost_reflect::ReflectMessage::transcode_to_dynamic(self);
22                serde::Serialize::serialize(&message, serializer)
23            }
24        }
25    };
26
27    TokenStream::from(expanded)
28}
29
30#[proc_macro_derive(Deserialize_proto)]
31pub fn derive_deserialize(input: TokenStream) -> TokenStream {
32    let input = parse_macro_input!(input as DeriveInput);
33    let ident = input.ident;
34
35    match input.data {
36        syn::Data::Struct(_) => (),
37        _ => return Default::default(),
38    };
39
40    let expanded = quote! {
41        impl<'de> serde::Deserialize<'de> for #ident {
42            fn deserialize<D>(deserializer: D) -> Result<#ident, D::Error>
43            where
44                D: serde::Deserializer<'de>,
45            {
46                let concrete_msg: #ident = Default::default();
47                let descriptor = prost_reflect::ReflectMessage::descriptor(&concrete_msg);
48                let dynamic_msg = prost_reflect::DynamicMessage::deserialize(descriptor, deserializer)?;
49
50                Ok(dynamic_msg.transcode_to().expect("failed to convert DynamicMessage to concrete Message!"))
51            }
52        }
53    };
54
55    TokenStream::from(expanded)
56}