summaryrefslogtreecommitdiffstats
path: root/vendor/synstructure/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/synstructure/src/lib.rs')
-rw-r--r--vendor/synstructure/src/lib.rs237
1 files changed, 217 insertions, 20 deletions
diff --git a/vendor/synstructure/src/lib.rs b/vendor/synstructure/src/lib.rs
index 2cd2b8801..5c5cd0c28 100644
--- a/vendor/synstructure/src/lib.rs
+++ b/vendor/synstructure/src/lib.rs
@@ -149,6 +149,14 @@
//! For more example usage, consider investigating the `abomonation_derive` crate,
//! which makes use of this crate, and is fairly simple.
+#![allow(
+ clippy::default_trait_access,
+ clippy::missing_errors_doc,
+ clippy::missing_panics_doc,
+ clippy::must_use_candidate,
+ clippy::needless_pass_by_value
+)]
+
#[cfg(all(
not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "wasi"))),
feature = "proc-macro"
@@ -182,6 +190,7 @@ use proc_macro2::{Span, TokenStream, TokenTree};
pub mod macros;
/// Changes how bounds are added
+#[allow(clippy::manual_non_exhaustive)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum AddBounds {
/// Add for fields and generics
@@ -238,7 +247,7 @@ fn fetch_generics<'a>(set: &[bool], generics: &'a Generics) -> Vec<&'a Ident> {
for (&seen, param) in set.iter().zip(generics.params.iter()) {
if seen {
if let GenericParam::Type(tparam) = param {
- tys.push(&tparam.ident)
+ tys.push(&tparam.ident);
}
}
}
@@ -250,7 +259,7 @@ fn sanitize_ident(s: &str) -> Ident {
let mut res = String::with_capacity(s.len());
for mut c in s.chars() {
if !UnicodeXID::is_xid_continue(c) {
- c = '_'
+ c = '_';
}
// Deduplicate consecutive _ characters.
if res.ends_with('_') && c == '_' {
@@ -443,7 +452,7 @@ pub struct VariantInfo<'a> {
original_length: usize,
}
-/// Helper function used by the VariantInfo constructor. Walks all of the types
+/// Helper function used by the `VariantInfo` constructor. Walks all of the types
/// in `field` and returns a list of the type parameters from `ty_params` which
/// are referenced in the field.
fn get_ty_params(field: &Field, generics: &Generics) -> Vec<bool> {
@@ -473,7 +482,7 @@ fn get_ty_params(field: &Field, generics: &Generics) -> Vec<bool> {
for r in &mut self.result {
*r = true;
}
- visit::visit_type_macro(self, x)
+ visit::visit_type_macro(self, x);
}
}
@@ -657,7 +666,7 @@ impl<'a> VariantInfo<'a> {
func(field, i).to_tokens(t);
quote!(,).to_tokens(t);
}
- })
+ });
}
Fields::Named(FieldsNamed { named, .. }) => {
token::Brace::default().surround(&mut t, |t| {
@@ -667,7 +676,7 @@ impl<'a> VariantInfo<'a> {
func(field, i).to_tokens(t);
quote!(,).to_tokens(t);
}
- })
+ });
}
}
t
@@ -803,6 +812,71 @@ impl<'a> VariantInfo<'a> {
self
}
+ /// Iterates all the bindings of this `Variant` object and uses a closure to determine if a
+ /// binding should be removed. If the closure returns `true` the binding is removed from the
+ /// variant. If the closure returns `false`, the binding remains in the variant.
+ ///
+ /// All the removed bindings are moved to a new `Variant` object which is otherwise identical
+ /// to the current one. To understand the effects of removing a binding from a variant check
+ /// the [`VariantInfo::filter`] documentation.
+ ///
+ /// # Example
+ /// ```
+ /// # use synstructure::*;
+ /// let di: syn::DeriveInput = syn::parse_quote! {
+ /// enum A {
+ /// B{ a: i32, b: i32 },
+ /// C{ a: u32 },
+ /// }
+ /// };
+ /// let mut s = Structure::new(&di);
+ ///
+ /// let mut with_b = &mut s.variants_mut()[0];
+ ///
+ /// let with_a = with_b.drain_filter(|bi| {
+ /// bi.ast().ident == Some(quote::format_ident!("a"))
+ /// });
+ ///
+ /// assert_eq!(
+ /// with_a.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
+ ///
+ /// quote!{
+ /// A::B{ a: ref __binding_0, .. } => {
+ /// { println!("{:?}", __binding_0) }
+ /// }
+ /// }.to_string()
+ /// );
+ ///
+ /// assert_eq!(
+ /// with_b.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
+ ///
+ /// quote!{
+ /// A::B{ b: ref __binding_1, .. } => {
+ /// { println!("{:?}", __binding_1) }
+ /// }
+ /// }.to_string()
+ /// );
+ /// ```
+ #[allow(clippy::return_self_not_must_use)]
+ pub fn drain_filter<F>(&mut self, mut f: F) -> Self
+ where
+ F: FnMut(&BindingInfo<'_>) -> bool,
+ {
+ let mut other = VariantInfo {
+ prefix: self.prefix,
+ bindings: vec![],
+ ast: self.ast,
+ generics: self.generics,
+ original_length: self.original_length,
+ };
+
+ let (other_bindings, self_bindings) = self.bindings.drain(..).partition(&mut f);
+ other.bindings = other_bindings;
+ self.bindings = self_bindings;
+
+ other
+ }
+
/// Remove the binding at the given index.
///
/// # Panics
@@ -848,7 +922,7 @@ impl<'a> VariantInfo<'a> {
F: FnMut(&BindingInfo<'_>) -> BindStyle,
{
for binding in &mut self.bindings {
- binding.style = f(&binding);
+ binding.style = f(binding);
}
self
}
@@ -981,21 +1055,12 @@ impl<'a> Structure<'a> {
})
.collect::<Vec<_>>(),
Data::Struct(data) => {
- // SAFETY NOTE: Normally putting an `Expr` in static storage
- // wouldn't be safe, because it could contain `Term` objects
- // which use thread-local interning. However, this static always
- // contains the value `None`. Thus, it will never contain any
- // unsafe values.
- struct UnsafeMakeSync(Option<(token::Eq, Expr)>);
- unsafe impl Sync for UnsafeMakeSync {}
- static NONE_DISCRIMINANT: UnsafeMakeSync = UnsafeMakeSync(None);
-
vec![VariantInfo::new(
VariantAst {
attrs: &ast.attrs,
ident: &ast.ident,
fields: &data.fields,
- discriminant: &NONE_DISCRIMINANT.0,
+ discriminant: &None,
},
None,
&ast.generics,
@@ -1234,6 +1299,75 @@ impl<'a> Structure<'a> {
self
}
+ /// Iterates all the bindings of this `Structure` object and uses a closure to determine if a
+ /// binding should be removed. If the closure returns `true` the binding is removed from the
+ /// structure. If the closure returns `false`, the binding remains in the structure.
+ ///
+ /// All the removed bindings are moved to a new `Structure` object which is otherwise identical
+ /// to the current one. To understand the effects of removing a binding from a structure check
+ /// the [`Structure::filter`] documentation.
+ ///
+ /// # Example
+ /// ```
+ /// # use synstructure::*;
+ /// let di: syn::DeriveInput = syn::parse_quote! {
+ /// enum A {
+ /// B{ a: i32, b: i32 },
+ /// C{ a: u32 },
+ /// }
+ /// };
+ /// let mut with_b = Structure::new(&di);
+ ///
+ /// let with_a = with_b.drain_filter(|bi| {
+ /// bi.ast().ident == Some(quote::format_ident!("a"))
+ /// });
+ ///
+ /// assert_eq!(
+ /// with_a.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
+ ///
+ /// quote!{
+ /// A::B{ a: ref __binding_0, .. } => {
+ /// { println!("{:?}", __binding_0) }
+ /// }
+ /// A::C{ a: ref __binding_0, } => {
+ /// { println!("{:?}", __binding_0) }
+ /// }
+ /// }.to_string()
+ /// );
+ ///
+ /// assert_eq!(
+ /// with_b.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
+ ///
+ /// quote!{
+ /// A::B{ b: ref __binding_1, .. } => {
+ /// { println!("{:?}", __binding_1) }
+ /// }
+ /// A::C{ .. } => {
+ ///
+ /// }
+ /// }.to_string()
+ /// );
+ /// ```
+ #[allow(clippy::return_self_not_must_use)]
+ pub fn drain_filter<F>(&mut self, mut f: F) -> Self
+ where
+ F: FnMut(&BindingInfo<'_>) -> bool,
+ {
+ Self {
+ variants: self
+ .variants
+ .iter_mut()
+ .map(|variant| variant.drain_filter(&mut f))
+ .collect(),
+ omitted_variants: self.omitted_variants,
+ underscore_const: self.underscore_const,
+ ast: self.ast,
+ extra_impl: self.extra_impl.clone(),
+ extra_predicates: self.extra_predicates.clone(),
+ add_bounds: self.add_bounds,
+ }
+ }
+
/// Specify additional where predicate bounds which should be generated by
/// impl-generating functions such as `gen_impl`, `bound_impl`, and
/// `unsafe_bound_impl`.
@@ -1367,6 +1501,69 @@ impl<'a> Structure<'a> {
}
self
}
+ /// Iterates all the variants of this `Structure` object and uses a closure to determine if a
+ /// variant should be removed. If the closure returns `true` the variant is removed from the
+ /// structure. If the closure returns `false`, the variant remains in the structure.
+ ///
+ /// All the removed variants are moved to a new `Structure` object which is otherwise identical
+ /// to the current one. To understand the effects of removing a variant from a structure check
+ /// the [`Structure::filter_variants`] documentation.
+ ///
+ /// # Example
+ /// ```
+ /// # use synstructure::*;
+ /// let di: syn::DeriveInput = syn::parse_quote! {
+ /// enum A {
+ /// B(i32, i32),
+ /// C(u32),
+ /// }
+ /// };
+ ///
+ /// let mut with_c = Structure::new(&di);
+ ///
+ /// let with_b = with_c.drain_filter_variants(|v| v.ast().ident == "B");
+ ///
+ /// assert_eq!(
+ /// with_c.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
+ ///
+ /// quote!{
+ /// A::C(ref __binding_0,) => {
+ /// { println!("{:?}", __binding_0) }
+ /// }
+ /// }.to_string()
+ /// );
+ ///
+ /// assert_eq!(
+ /// with_b.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
+ ///
+ /// quote!{
+ /// A::B(ref __binding_0, ref __binding_1,) => {
+ /// { println!("{:?}", __binding_0) }
+ /// { println!("{:?}", __binding_1) }
+ /// }
+ /// }.to_string()
+ /// );
+ #[allow(clippy::return_self_not_must_use)]
+ pub fn drain_filter_variants<F>(&mut self, mut f: F) -> Self
+ where
+ F: FnMut(&VariantInfo<'_>) -> bool,
+ {
+ let mut other = Self {
+ variants: vec![],
+ omitted_variants: self.omitted_variants,
+ underscore_const: self.underscore_const,
+ ast: self.ast,
+ extra_impl: self.extra_impl.clone(),
+ extra_predicates: self.extra_predicates.clone(),
+ add_bounds: self.add_bounds,
+ };
+
+ let (other_variants, self_variants) = self.variants.drain(..).partition(&mut f);
+ other.variants = other_variants;
+ self.variants = self_variants;
+
+ other
+ }
/// Remove the variant at the given index.
///
@@ -2049,8 +2246,8 @@ impl<'a> Structure<'a> {
/// };
/// ```
///
- /// The `Structure` may also be confired with the [`underscore_const`] method
- /// to generate `const _` instead.
+ /// The `Structure` may also be configured with the
+ /// [`Structure::underscore_const`] method to generate `const _` instead.
///
/// ```ignore
/// const _: () = {
@@ -2342,7 +2539,7 @@ impl<'a> Structure<'a> {
/// }),
/// "# [
/// allow (
-/// non_upper_case_globals )
+/// non_upper_case_globals)
/// ]
/// const _DERIVE_krate_Trait_FOR_A : (
/// )