1//! Traits and types used for tracking the usage of generic parameters through a proc-macro input.
2//!
3//! When generating trait impls, libraries often want to automatically figure out which type parameters
4//! are used in which fields, and then emit bounds that will produce the most permissive compilable
5//! code.
6//!
7//! # Usage
8//!
9//! ## Example 1: Filtering
10//! This example accepts a proc-macro input, then finds all lifetimes and type parameters used
11//! by private fields.
12//!
13//! ```rust
14//! # extern crate darling_core;
15//! # extern crate syn;
16//! #
17//! # // in real-world usage, import from `darling`
18//! # use darling_core::usage::{self, CollectLifetimes, CollectTypeParams, GenericsExt, Purpose};
19//! # use syn::{Data, DeriveInput, GenericParam, Generics, Visibility};
20//! #
21//! # #[allow(dead_code)]
22//! fn process(input: &DeriveInput) -> Generics {
23//! let type_params = input.generics.declared_type_params();
24//! let lifetimes = input.generics.declared_lifetimes();
25//!
26//! let mut ret_generics = input.generics.clone();
27//!
28//! if let Data::Struct(ref body) = input.data {
29//! let internal_fields = body
30//! .fields
31//! .iter()
32//! .filter(|field| field.vis == Visibility::Inherited)
33//! .collect::<Vec<_>>();
34//!
35//! let int_type_params = internal_fields
36//! .collect_type_params(&Purpose::BoundImpl.into(), &type_params);
37//!
38//! // We could reuse the vec from above, but here we'll instead
39//! // directly consume the chained iterator.
40//! let int_lifetimes = body
41//! .fields
42//! .iter()
43//! .filter(|field| field.vis == Visibility::Inherited)
44//! .collect_lifetimes(&Purpose::BoundImpl.into(), &lifetimes);
45//!
46//!
47//! ret_generics.params = ret_generics
48//! .params
49//! .into_iter()
50//! .filter(|gp| {
51//! match *gp {
52//! GenericParam::Type(ref ty) => int_type_params.contains(&ty.ident),
53//! GenericParam::Lifetime(ref lt) => int_lifetimes.contains(&lt.lifetime),
54//! _ => true,
55//! }
56//! })
57//! .collect();
58//! }
59//!
60//! ret_generics
61//! }
62//!
63//! # fn main() {}
64//! ```
65//!
66//! ## Example 2: Integrating with `FromDeriveInput`
67//! It is possible to use `darling`'s magic fields feature in tandem with the `usage` feature set.
68//! While there is no custom derive for `UsesTypeParams` or `UsesLifetimes`, there are macros to
69//! generate impls.
70//!
71//! ```rust,ignore
72//! #![allow(dead_code)]
73//!
74//! #[derive(FromField)]
75//! #[darling(attributes(speak))]
76//! struct SpeakerField {
77//! ident: Option<syn::Ident>,
78//! ty: syn::Type,
79//! #[darling(default)]
80//! volume: Option<u32>,
81//! }
82//!
83//! uses_type_params!(SpeakerField, ty);
84//! uses_lifetimes!(SpeakerField, ty);
85//!
86//! #[derive(FromDeriveInput)]
87//! struct SpeakerOptions {
88//! generics: syn::Generics,
89//! data: darling::ast::Data<darling::util::Ignored, SpeakerField>,
90//! }
91//! ```
92//!
93//! At this point, you are able to call `uses_type_params` on `SpeakerOptions.data`, or any filtered
94//! view of it. `darling` internally uses this in conjunction with the `skip` meta-item to determine
95//! which type parameters don't require the `FromMeta` bound in generated impls.
96//!
97//! **Note:** If you are performing operations referencing generic params in meta-items parsed by `darling`,
98//! you should determine if those impact the emitted code and wire up `UsesTypeParams` accordingly for
99//! your field/variant.
100
101mod generics_ext;
102mod ident_set;
103mod lifetimes;
104mod options;
105mod type_params;
106
107pub use self::generics_ext::GenericsExt;
108pub use self::ident_set::{IdentRefSet, IdentSet};
109pub use self::lifetimes::{CollectLifetimes, LifetimeRefSet, LifetimeSet, UsesLifetimes};
110pub use self::options::{Options, Purpose};
111pub use self::type_params::{CollectTypeParams, UsesTypeParams};
112