-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
traits.rs
107 lines (96 loc) · 2.01 KB
/
traits.rs
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
use syn::{
visit_mut::{self, VisitMut},
*,
};
use crate::utils::*;
use super::Arg;
pub(super) fn collect_impl_traits(args: &mut Vec<Arg>, ty: &mut Type) {
if let Some(traits) = collect(ty) {
parse(args, traits);
}
}
fn collect(ty: &mut Type) -> Option<Vec<Path>> {
let mut traits = Vec::new();
ImplTraits::new(&mut traits).visit_type_mut(ty);
if traits.is_empty() {
None
} else {
Some(traits)
}
}
fn parse(args: &mut Vec<Arg>, traits: Vec<Path>) {
traits.into_iter().map(Arg::from).for_each(|t| {
if !args.contains(&t) && TRAITS.contains(&&*t.to_trimed_string()) {
args.push(t);
}
});
}
struct ImplTraits<'a> {
traits: &'a mut Vec<Path>,
}
impl<'a> ImplTraits<'a> {
fn new(traits: &'a mut Vec<Path>) -> Self {
Self { traits }
}
}
impl VisitMut for ImplTraits<'_> {
fn visit_type_impl_trait_mut(&mut self, ty: &mut TypeImplTrait) {
visit_mut::visit_type_impl_trait_mut(self, ty);
ty.bounds.iter().for_each(|ty| {
if let TypeParamBound::Trait(ty) = ty {
self.traits.push(path(ty.path.segments.iter().map(|ty| ty.ident.clone().into())));
}
});
}
}
const TRAITS: &[&str] = &[
"Clone",
"Copy",
"PartialEq",
"Eq",
"PartialOrd",
"Ord",
"Hash",
// core
"AsRef",
"AsMut",
"Debug",
"fmt::Debug",
"Display",
"fmt::Display",
"fmt::Binary",
"fmt::LowerExp",
"fmt::LowerHex",
"fmt::Octal",
"fmt::Pointer",
"fmt::UpperExp",
"fmt::UpperHex",
"fmt::Write",
"Iterator",
"DoubleEndedIterator",
"ExactSizeIterator",
"FusedIterator",
"TrustedLen",
"Extend",
"Deref",
"DerefMut",
"Index",
"IndexMut",
"RangeBounds",
"Fn",
"FnMut",
"FnOnce",
"Generator",
"Future",
// std
"Read",
"io::Read",
"BufRead",
"io::BufRead",
"Write",
"io::Write",
"Seek",
"io::Seek",
"Error",
"error::Error",
];