Skip to content

Commit 43ee018

Browse files
committed
Rework trait dispatch
1 parent 8b641df commit 43ee018

21 files changed

+529
-528
lines changed

src/attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use self::{
1515
default::Default,
1616
field::FieldAttr,
1717
incomparable::Incomparable,
18-
item::{DeriveTrait, DeriveWhere, ItemAttr},
18+
item::{DeriveWhere, ItemAttr},
1919
skip::{Skip, SkipGroup},
2020
variant::VariantAttr,
2121
};

src/attr/field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use syn::{spanned::Spanned, Attribute, Meta, Result};
44

55
use crate::{util::MetaListExt, DeriveWhere, Error, Skip, DERIVE_WHERE};
66
#[cfg(feature = "zeroize")]
7-
use crate::{Trait, TraitImpl, ZeroizeFqs};
7+
use crate::{Trait, ZeroizeFqs};
88

99
/// Attributes on field.
1010
#[derive(Default)]

src/attr/incomparable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use proc_macro2::Span;
44
use syn::{spanned::Spanned, Meta, Result};
55

6-
use crate::{attr::DeriveTrait, DeriveWhere, Error};
6+
use crate::{trait_::DeriveTrait, DeriveWhere, Error};
77

88
/// Stores if this variant should be incomparable when implementing
99
/// [`PartialEq`] or [`PartialOrd`].

src/attr/item.rs

Lines changed: 5 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
//! [`Attribute`] parsing for items.
22
3-
use std::{borrow::Cow, ops::Deref};
3+
use std::borrow::Cow;
44

55
use proc_macro2::Span;
66
use syn::{
77
parse::{discouraged::Speculative, Parse, ParseStream},
88
punctuated::Punctuated,
99
spanned::Spanned,
10-
Attribute, BoundLifetimes, Data, Ident, Meta, Path, PredicateType, Result, Token, TraitBound,
11-
TraitBoundModifier, Type, TypeParamBound, TypePath, WhereClause, WherePredicate,
10+
Attribute, BoundLifetimes, Data, Ident, Meta, PredicateType, Result, Token, Type, TypePath,
11+
WhereClause, WherePredicate,
1212
};
1313

14-
use crate::{
15-
util::{self, MetaListExt},
16-
Error, Incomparable, Item, Skip, SkipGroup, Trait, TraitImpl, DERIVE_WHERE,
17-
};
14+
use crate::{trait_::DeriveTrait, Error, Incomparable, Item, Skip, SkipGroup, Trait, DERIVE_WHERE};
1815

1916
/// Attributes on item.
2017
#[derive(Default)]
@@ -259,7 +256,7 @@ impl DeriveWhere {
259256
pub fn any_skip(&self) -> bool {
260257
self.traits
261258
.iter()
262-
.any(|trait_| SkipGroup::trait_supported_by_skip_all(**trait_))
259+
.any(|trait_| SkipGroup::trait_supported_by_skip_all(***trait_))
263260
}
264261

265262
/// Create [`WhereClause`] for the given parameters.
@@ -353,174 +350,3 @@ impl Parse for Generic {
353350
}
354351
}
355352
}
356-
357-
/// Trait to implement.
358-
#[derive(Eq, PartialEq)]
359-
pub enum DeriveTrait {
360-
/// [`Clone`].
361-
Clone,
362-
/// [`Copy`].
363-
Copy,
364-
/// [`Debug`](std::fmt::Debug).
365-
Debug,
366-
/// [`Default`].
367-
Default,
368-
/// [`Eq`].
369-
Eq,
370-
/// [`Hash`](std::hash::Hash).
371-
Hash,
372-
/// [`Ord`].
373-
Ord,
374-
/// [`PartialEq`].
375-
PartialEq,
376-
/// [`PartialOrd`].
377-
PartialOrd,
378-
/// [`Zeroize`](https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html).
379-
#[cfg(feature = "zeroize")]
380-
Zeroize {
381-
/// [`Zeroize`](https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html) path.
382-
crate_: Option<Path>,
383-
},
384-
/// [`ZeroizeOnDrop`](https://docs.rs/zeroize/latest/zeroize/trait.ZeroizeOnDrop.html).
385-
#[cfg(feature = "zeroize")]
386-
ZeroizeOnDrop {
387-
/// [`ZeroizeOnDrop`](https://docs.rs/zeroize/latest/zeroize/trait.ZeroizeOnDrop.html) path.
388-
crate_: Option<Path>,
389-
/// If `Drop` should be implemented.
390-
no_drop: bool,
391-
},
392-
}
393-
394-
impl Deref for DeriveTrait {
395-
type Target = Trait;
396-
397-
fn deref(&self) -> &Self::Target {
398-
use DeriveTrait::*;
399-
400-
match self {
401-
Clone => &Trait::Clone,
402-
Copy => &Trait::Copy,
403-
Debug => &Trait::Debug,
404-
Default => &Trait::Default,
405-
Eq => &Trait::Eq,
406-
Hash => &Trait::Hash,
407-
Ord => &Trait::Ord,
408-
PartialEq => &Trait::PartialEq,
409-
PartialOrd => &Trait::PartialOrd,
410-
#[cfg(feature = "zeroize")]
411-
Zeroize { .. } => &Trait::Zeroize,
412-
#[cfg(feature = "zeroize")]
413-
ZeroizeOnDrop { .. } => &Trait::ZeroizeOnDrop,
414-
}
415-
}
416-
}
417-
418-
impl PartialEq<Trait> for &DeriveTrait {
419-
fn eq(&self, other: &Trait) -> bool {
420-
let trait_: &Trait = self;
421-
trait_ == other
422-
}
423-
}
424-
425-
impl DeriveTrait {
426-
/// Returns fully qualified [`Path`] for this trait.
427-
pub fn path(&self) -> Path {
428-
use DeriveTrait::*;
429-
430-
match self {
431-
Clone => util::path_from_root_and_strs(self.crate_(), &["clone", "Clone"]),
432-
Copy => util::path_from_root_and_strs(self.crate_(), &["marker", "Copy"]),
433-
Debug => util::path_from_root_and_strs(self.crate_(), &["fmt", "Debug"]),
434-
Default => util::path_from_root_and_strs(self.crate_(), &["default", "Default"]),
435-
Eq => util::path_from_root_and_strs(self.crate_(), &["cmp", "Eq"]),
436-
Hash => util::path_from_root_and_strs(self.crate_(), &["hash", "Hash"]),
437-
Ord => util::path_from_root_and_strs(self.crate_(), &["cmp", "Ord"]),
438-
PartialEq => util::path_from_root_and_strs(self.crate_(), &["cmp", "PartialEq"]),
439-
PartialOrd => util::path_from_root_and_strs(self.crate_(), &["cmp", "PartialOrd"]),
440-
#[cfg(feature = "zeroize")]
441-
Zeroize { .. } => util::path_from_root_and_strs(self.crate_(), &["Zeroize"]),
442-
#[cfg(feature = "zeroize")]
443-
ZeroizeOnDrop { .. } => util::path_from_root_and_strs(self.crate_(), &["ZeroizeOnDrop"]),
444-
}
445-
}
446-
447-
/// Returns the path to the root crate for this trait.
448-
pub fn crate_(&self) -> Path {
449-
use DeriveTrait::*;
450-
451-
match self {
452-
Clone => util::path_from_strs(&["core"]),
453-
Copy => util::path_from_strs(&["core"]),
454-
Debug => util::path_from_strs(&["core"]),
455-
Default => util::path_from_strs(&["core"]),
456-
Eq => util::path_from_strs(&["core"]),
457-
Hash => util::path_from_strs(&["core"]),
458-
Ord => util::path_from_strs(&["core"]),
459-
PartialEq => util::path_from_strs(&["core"]),
460-
PartialOrd => util::path_from_strs(&["core"]),
461-
#[cfg(feature = "zeroize")]
462-
Zeroize { crate_, .. } => {
463-
if let Some(crate_) = crate_ {
464-
crate_.clone()
465-
} else {
466-
util::path_from_strs(&["zeroize"])
467-
}
468-
}
469-
#[cfg(feature = "zeroize")]
470-
ZeroizeOnDrop { crate_, .. } => {
471-
if let Some(crate_) = crate_ {
472-
crate_.clone()
473-
} else {
474-
util::path_from_strs(&["zeroize"])
475-
}
476-
}
477-
}
478-
}
479-
480-
/// Returns where-clause bounds for the trait in respect of the item type.
481-
fn where_bounds(&self, data: &Item) -> Punctuated<TypeParamBound, Token![+]> {
482-
let mut list = Punctuated::new();
483-
484-
list.push(TypeParamBound::Trait(TraitBound {
485-
paren_token: None,
486-
modifier: TraitBoundModifier::None,
487-
lifetimes: None,
488-
path: self.path(),
489-
}));
490-
491-
// Add bounds specific to the trait.
492-
if let Some(bound) = self.additional_where_bounds(data) {
493-
list.push(bound)
494-
}
495-
496-
list
497-
}
498-
499-
/// Create [`DeriveTrait`] from [`ParseStream`].
500-
fn from_stream(span: Span, data: &Data, input: ParseStream) -> Result<(Span, Self)> {
501-
match Meta::parse(input) {
502-
Ok(meta) => {
503-
let trait_ = Trait::from_path(meta.path())?;
504-
505-
if let Data::Union(_) = data {
506-
// Make sure this `Trait` supports unions.
507-
if !trait_.supports_union() {
508-
return Err(Error::union(span));
509-
}
510-
}
511-
512-
match &meta {
513-
Meta::Path(path) => Ok((path.span(), trait_.default_derive_trait())),
514-
Meta::List(list) => {
515-
let nested = list.parse_non_empty_nested_metas()?;
516-
517-
// This will return an error if no options are supported.
518-
Ok((list.span(), trait_.parse_derive_trait(meta.span(), nested)?))
519-
}
520-
Meta::NameValue(name_value) => Err(Error::option_syntax(name_value.span())),
521-
}
522-
}
523-
Err(error) => Err(Error::trait_syntax(error.span())),
524-
}
525-
}
526-
}

src/attr/skip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::default::Default;
44

55
use syn::{spanned::Spanned, Meta, Path, Result};
66

7-
use crate::{attr::DeriveTrait, util::MetaListExt, DeriveWhere, Error, Trait};
7+
use crate::{trait_::DeriveTrait, util::MetaListExt, DeriveWhere, Error, Trait};
88

99
/// Stores what [`Trait`]s to skip this field or variant for.
1010
#[cfg_attr(test, derive(Debug))]

src/attr/zeroize_fqs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use syn::{spanned::Spanned, Meta, Result};
44

5-
use crate::{util::MetaListExt, DeriveWhere, Error, Trait, TraitImpl};
5+
use crate::{util::MetaListExt, DeriveWhere, Error, Trait};
66

77
/// Stores if this field should use FQS to call [`Zeroize::zeroize`](https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html#tymethod.zeroize).
88
#[derive(Default)]

src/input.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use syn::{DeriveInput, GenericParam, Generics, ImplGenerics, Result, TypeGeneric
77
use crate::DeriveTrait;
88
#[cfg(not(feature = "nightly"))]
99
use crate::Discriminant;
10-
use crate::{Data, DeriveWhere, Either, Error, Item, ItemAttr, Trait};
10+
use crate::{
11+
trait_::{zeroize::Zeroize, zeroize_on_drop::ZeroizeOnDrop},
12+
Data, DeriveWhere, Either, Error, Item, ItemAttr, Trait,
13+
};
1114

1215
/// Parsed input.
1316
pub struct Input<'a> {
@@ -170,7 +173,7 @@ impl<'a> Input<'a> {
170173
}
171174

172175
// Any field is skipped with a corresponding `Trait`.
173-
if item.any_skip_trait(**trait_) {
176+
if item.any_skip_trait(***trait_) {
174177
continue;
175178
}
176179

@@ -181,21 +184,17 @@ impl<'a> Input<'a> {
181184

182185
#[cfg(feature = "zeroize")]
183186
{
184-
// `Zeroize(crate = ..)` or `ZeroizeOnDrop(crate = ..)` is used.
185-
if let DeriveTrait::Zeroize { crate_: Some(_) }
186-
| DeriveTrait::ZeroizeOnDrop {
187+
// `Zeroize(crate = ..)`, `ZeroizeOnDrop(crate = ..)` or
188+
// `ZeroizeOnDrop(no_drop)` is used.
189+
if let DeriveTrait::Zeroize(Zeroize { crate_: Some(_) })
190+
| DeriveTrait::ZeroizeOnDrop(ZeroizeOnDrop {
187191
crate_: Some(_), ..
188-
} = *trait_
192+
})
193+
| DeriveTrait::ZeroizeOnDrop(ZeroizeOnDrop { no_drop: true, .. }) = *trait_
189194
{
190195
continue;
191196
}
192197

193-
// `ZeroizeOnDrop(no_drop)` is used.
194-
#[cfg(feature = "zeroize-on-drop")]
195-
if let DeriveTrait::ZeroizeOnDrop { no_drop: true, .. } = *trait_ {
196-
continue;
197-
}
198-
199198
// `Zeroize(fqs)` is used on any field.
200199
if trait_ == Trait::Zeroize && item.any_fqs() {
201200
continue;

src/lib.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -414,15 +414,12 @@ use self::attr::ZeroizeFqs;
414414
#[cfg(not(feature = "nightly"))]
415415
use self::item::Discriminant;
416416
use self::{
417-
attr::{
418-
Default, DeriveTrait, DeriveWhere, FieldAttr, Incomparable, ItemAttr, Skip, SkipGroup,
419-
VariantAttr,
420-
},
417+
attr::{Default, DeriveWhere, FieldAttr, Incomparable, ItemAttr, Skip, SkipGroup, VariantAttr},
421418
data::{Data, DataType, Field, SimpleType},
422419
error::Error,
423420
input::Input,
424421
item::Item,
425-
trait_::{Trait, TraitImpl},
422+
trait_::{DeriveTrait, Trait, TraitImpl},
426423
util::Either,
427424
};
428425

@@ -644,9 +641,9 @@ fn generate_impl(
644641
let body = generate_body(derive_where, trait_, item, generics);
645642

646643
let ident = item.ident();
647-
let mut output = trait_.impl_item(trait_, imp, ident, ty, &where_clause, body);
644+
let mut output = trait_.impl_item(imp, ident, ty, &where_clause, body);
648645

649-
if let Some((path, body)) = trait_.additional_impl(trait_) {
646+
if let Some((path, body)) = trait_.additional_impl() {
650647
output.extend(quote! {
651648
#[automatically_derived]
652649
impl #imp #path for #ident #ty
@@ -669,16 +666,16 @@ fn generate_body(
669666
) -> TokenStream {
670667
match &item {
671668
Item::Item(data) => {
672-
let body = trait_.build_body(derive_where, trait_, data);
673-
trait_.build_signature(derive_where, item, generics, trait_, &body)
669+
let body = trait_.build_body(derive_where, data);
670+
trait_.build_signature(derive_where, item, generics, &body)
674671
}
675672
Item::Enum { variants, .. } => {
676673
let body: TokenStream = variants
677674
.iter()
678-
.map(|data| trait_.build_body(derive_where, trait_, data))
675+
.map(|data| trait_.build_body(derive_where, data))
679676
.collect();
680677

681-
trait_.build_signature(derive_where, item, generics, trait_, &body)
678+
trait_.build_signature(derive_where, item, generics, &body)
682679
}
683680
}
684681
}

0 commit comments

Comments
 (0)