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
//! Traits and types used for tracking the usage of generic parameters through a proc-macro input. //! //! When generating trait impls, libraries often want to automatically figure out which type parameters //! are used in which fields, and then emit bounds that will produce the most permissive compilable //! code. //! //! # Usage //! //! ## Example 1: Filtering //! This example accepts a proc-macro input, then finds all lifetimes and type parameters used //! by private fields. //! //! ```rust //! # extern crate darling_core; //! # extern crate syn; //! # //! # // in real-world usage, import from `darling` //! # use darling_core::usage::{self, CollectLifetimes, CollectTypeParams, GenericsExt, Purpose}; //! # use syn::{Data, DeriveInput, GenericParam, Generics, Visibility}; //! # //! # #[allow(dead_code)] //! fn process(input: &DeriveInput) -> Generics { //! let type_params = input.generics.declared_type_params(); //! let lifetimes = input.generics.declared_lifetimes(); //! //! let mut ret_generics = input.generics.clone(); //! //! if let Data::Struct(ref body) = input.data { //! let internal_fields = body //! .fields //! .iter() //! .filter(|field| field.vis == Visibility::Inherited) //! .collect::<Vec<_>>(); //! //! let int_type_params = internal_fields //! .collect_type_params(&Purpose::BoundImpl.into(), &type_params); //! //! // We could reuse the vec from above, but here we'll instead //! // directly consume the chained iterator. //! let int_lifetimes = body //! .fields //! .iter() //! .filter(|field| field.vis == Visibility::Inherited) //! .collect_lifetimes(&Purpose::BoundImpl.into(), &lifetimes); //! //! //! ret_generics.params = ret_generics //! .params //! .into_iter() //! .filter(|gp| { //! match *gp { //! GenericParam::Type(ref ty) => int_type_params.contains(&ty.ident), //! GenericParam::Lifetime(ref lt) => int_lifetimes.contains(<.lifetime), //! _ => true, //! } //! }) //! .collect(); //! } //! //! ret_generics //! } //! //! # fn main() {} //! ``` //! //! ## Example 2: Integrating with `FromDeriveInput` //! It is possible to use `darling`'s magic fields feature in tandem with the `usage` feature set. //! While there is no custom derive for `UsesTypeParams` or `UsesLifetimes`, there are macros to //! generate impls. //! //! ```rust,ignore //! #![allow(dead_code)] //! //! #[derive(FromField)] //! #[darling(attributes(speak))] //! struct SpeakerField { //! ident: Option<syn::Ident>, //! ty: syn::Type, //! #[darling(default)] //! volume: Option<u32>, //! } //! //! uses_type_params!(SpeakerField, ty); //! uses_lifetimes!(SpeakerField, ty); //! //! #[derive(FromDeriveInput)] //! struct SpeakerOptions { //! generics: syn::Generics, //! data: darling::ast::Data<darling::util::Ignored, SpeakerField>, //! } //! ``` //! //! At this point, you are able to call `uses_type_params` on `SpeakerOptions.data`, or any filtered //! view of it. `darling` internally uses this in conjunction with the `skip` meta-item to determine //! which type parameters don't require the `FromMeta` bound in generated impls. //! //! **Note:** If you are performing operations referencing generic params in meta-items parsed by `darling`, //! you should determine if those impact the emitted code and wire up `UsesTypeParams` accordingly for //! your field/variant. mod generics_ext; mod ident_set; mod lifetimes; mod options; mod type_params; pub use self::generics_ext::GenericsExt; pub use self::ident_set::{IdentRefSet, IdentSet}; pub use self::lifetimes::{CollectLifetimes, LifetimeRefSet, LifetimeSet, UsesLifetimes}; pub use self::options::{Options, Purpose}; pub use self::type_params::{CollectTypeParams, UsesTypeParams};