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