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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
#![deny(missing_docs)] #![deny(missing_debug_implementations)] //! Traits and functions to make writing proc macros more ergonomic. //! //! The *roids* name is chosen because, although these functions make it easy to perform certain //! operation, they may not necessarily be a good idea =D! //! //! # Examples //! //! 1. Append additional `#[derive(..)]`s. //! //! This works for function-like or attribute proc macros. //! //! ```rust,ignore //! extern crate proc_macro; //! //! use proc_macro::TokenStream; //! use proc_macro_roids::DeriveInputDeriveExt; //! use quote::quote; //! use syn::{parse_macro_input, parse_quote, DeriveInput}; //! //! #[proc_macro_attribute] //! pub fn copy(_args: TokenStream, item: TokenStream) -> TokenStream { //! // Example input: //! // //! // #[derive(Debug)] //! // struct Struct; //! let mut ast = parse_macro_input!(item as DeriveInput); //! //! // Append the derives. //! let derives = parse_quote!(Clone, Copy); //! ast.append_derives(derives); //! //! // Example output: //! // //! // #[derive(Debug, Clone, Copy)] //! // struct Struct; //! TokenStream::from(quote! { #ast }) //! } //! ``` //! //! 2. Append named fields. //! //! This works for structs with named fields or unit structs. //! //! ```rust,ignore //! extern crate proc_macro; //! //! use proc_macro::TokenStream; //! use proc_macro_roids::FieldsNamedAppend; //! use quote::quote; //! use syn::{parse_macro_input, parse_quote, DeriveInput, FieldsNamed}; //! //! /// Example usage: //! /// //! /// ```rust //! /// use macro_crate::append_cd; //! /// //! /// #[append_cd] //! /// struct StructNamed { a: u32, b: i32 } //! /// ``` //! #[proc_macro_attribute] //! pub fn append_cd(_args: TokenStream, item: TokenStream) -> TokenStream { //! // Example input: //! // //! // struct StructNamed { a: u32, b: i32 } //! let mut ast = parse_macro_input!(item as DeriveInput); //! //! // Append the fields. //! let fields_additional: FieldsNamed = parse_quote!({ c: i64, d: usize }); //! ast.append_named(fields_additional); //! //! // Example output: //! // //! // struct StructNamed { a: u32, b: i32, c: i64, d: usize } //! TokenStream::from(quote! { #ast }) //! } //! ``` //! //! 3. Append unnamed fields (tuples). //! //! This works for structs with unnamed fields or unit structs. //! //! ```rust,ignore //! extern crate proc_macro; //! //! use proc_macro::TokenStream; //! use proc_macro_roids::FieldsUnnamedAppend; //! use quote::quote; //! use syn::{parse_macro_input, parse_quote, DeriveInput, FieldsUnnamed}; //! //! /// Example usage: //! /// //! /// ```rust //! /// use macro_crate::append_i64_usize; //! /// //! /// #[append_i64_usize] //! /// struct StructUnit; //! /// ``` //! #[proc_macro_attribute] //! pub fn append_i64_usize(_args: TokenStream, item: TokenStream) -> TokenStream { //! // Example input: //! // //! // struct StructUnit; //! let mut ast = parse_macro_input!(item as DeriveInput); //! //! // Append the fields. //! let fields_additional: FieldsUnnamed = parse_quote!((i64, usize)); //! ast.append_unnamed(fields_additional); //! //! // Example output: //! // //! // struct StructUnit(i64, usize); //! TokenStream::from(quote! { #ast }) //! } //! ``` //! //! 4. Get newtype inner `Field`. //! //! This works for structs with unnamed fields or unit structs. //! //! ```rust,ignore //! extern crate proc_macro; //! //! use proc_macro::TokenStream; //! use proc_macro_roids::DeriveInputNewtypeExt; //! use quote::quote; //! use syn::{parse_macro_input, parse_quote, DeriveInput, Type}; //! //! #[proc_macro_derive(Deref)] //! pub fn derive_deref(item: TokenStream) -> TokenStream { //! // Example input: //! // //! // #[derive(Deref)] //! // struct Newtype(u32); //! let mut ast = parse_macro_input!(item as DeriveInput); //! //! // Get the inner field. //! let inner_field = ast.inner_type(); //! //! // Implement `Deref` //! let type_name = &ast.ident; //! let token_stream_2 = quote! { //! #ast //! //! impl std::ops::Deref for #type_name { //! type Target = #inner_type; //! fn deref(&self) -> &Self::Target { //! &self.0 //! } //! } //! } //! TokenStream::from(token_stream_2) //! } //! ``` pub use crate::{ derive_input_derive_ext::DeriveInputDeriveExt, derive_input_newtype_ext::DeriveInputNewtypeExt, derive_input_struct_ext::DeriveInputStructExt, fields_named_append::FieldsNamedAppend, fields_unnamed_append::FieldsUnnamedAppend, util::{ident_concat, meta_list_contains, nested_meta_to_ident}, }; mod derive_input_derive_ext; mod derive_input_newtype_ext; mod derive_input_struct_ext; mod fields_named_append; mod fields_unnamed_append; mod util;