bee_common_derive/
lib.rs

1// Copyright 2020 IOTA Stiftung
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
4// the License. You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
9// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and limitations under the License.
11
12//! Derive macros for the bee-common crate.
13
14#![warn(missing_docs)]
15#![no_std]
16
17use quote::quote;
18use syn::{parse_macro_input, DeriveInput};
19
20/// Derives an implementation of the trait `core::fmt::Debug` for a secret type that doesn't leak its internal secret.
21/// Implements https://github.com/iotaledger/bee-rfcs/blob/master/text/0042-secret-debug-display.md.
22/// Based on https://github.com/dtolnay/syn/blob/master/examples/heapsize/heapsize_derive/src/lib.rs.
23#[proc_macro_derive(SecretDebug)]
24pub fn derive_secret_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
25    // Parse the input tokens into a syntax tree.
26    let input = parse_macro_input!(input as DeriveInput);
27    // Used in the quasi-quotation below as `#name`.
28    let name = input.ident;
29    // Get the different implementation elements from the input.
30    let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
31
32    // The generated implementation.
33    let expanded = quote! {
34        impl #impl_generics core::fmt::Debug for #name #ty_generics {
35            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36                write!(f, "<Omitted secret>")
37            }
38        }
39    };
40
41    expanded.into()
42}
43
44/// Derives an implementation of the trait `core::fmt::Display` for a secret type that doesn't leak its internal secret.
45/// Implements https://github.com/iotaledger/bee-rfcs/blob/master/text/0042-secret-debug-display.md.
46/// Based on https://github.com/dtolnay/syn/blob/master/examples/heapsize/heapsize_derive/src/lib.rs.
47#[proc_macro_derive(SecretDisplay)]
48pub fn derive_secret_display(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
49    // Parse the input tokens into a syntax tree.
50    let input = parse_macro_input!(input as DeriveInput);
51    // Used in the quasi-quotation below as `#name`.
52    let name = input.ident;
53    // Get the different implementation elements from the input.
54    let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
55
56    // The generated implementation.
57    let expanded = quote! {
58        impl #impl_generics core::fmt::Display for #name #ty_generics {
59            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60                write!(f, "<Omitted secret>")
61            }
62        }
63    };
64
65    expanded.into()
66}
67
68/// Derives an implementation of the trait `core::ops::Drop` for a secret type that calls `Zeroize::zeroize`.
69/// Implements https://github.com/iotaledger/bee-rfcs/blob/master/text/0044-secret-zeroize-drop.md.
70/// Based on https://github.com/dtolnay/syn/blob/master/examples/heapsize/heapsize_derive/src/lib.rs.
71#[proc_macro_derive(SecretDrop)]
72pub fn derive_secret_drop(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
73    // Parse the input tokens into a syntax tree.
74    let input = parse_macro_input!(input as DeriveInput);
75    // Used in the quasi-quotation below as `#name`.
76    let name = input.ident;
77    // Get the different implementation elements from the input.
78    let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
79
80    // The generated implementation.
81    let expanded = quote! {
82        impl #impl_generics core::ops::Drop for #name #ty_generics {
83            fn drop(&mut self) {
84                self.zeroize()
85            }
86        }
87    };
88
89    expanded.into()
90}