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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#![deny(missing_docs)]
#![allow(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::style)]
pub mod autoimpl;
mod default;
pub mod fields;
mod for_deref;
pub mod generics;
mod scope;
mod singleton;
pub use default::{find_attr_impl_default, AttrImplDefault, ImplDefault};
pub use for_deref::ForDeref;
pub use scope::{Scope, ScopeAttr, ScopeItem};
pub use singleton::{Singleton, SingletonField, SingletonScope};
#[derive(PartialEq, Eq)]
pub struct SimplePath(&'static [&'static str]);
impl std::fmt::Display for SimplePath {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
if !self.0.is_empty() {
write!(f, "{}", self.0[0])?;
for component in &self.0[1..] {
write!(f, "::{}", component)?;
}
}
Ok(())
}
}
impl SimplePath {
pub fn new(path: &'static [&'static str]) -> Self {
let mut is_empty = false;
for (i, s) in path.iter().enumerate() {
is_empty = is_empty && s.is_empty();
if i > 0 && s.is_empty() {
panic!("empty component");
}
}
if is_empty {
panic!("empty path");
}
SimplePath(path)
}
pub fn matches(&self, path: &syn::Path) -> bool {
let mut q = self.0;
assert!(!q.is_empty());
if path.leading_colon.is_some() && !q[0].is_empty() {
return false;
}
if q[0].is_empty() {
q = &q[1..];
}
if path.segments.len() != q.len() {
return false;
}
let mut first = true;
for (x, y) in path.segments.iter().zip(q.iter()) {
if !x.arguments.is_empty() {
return false;
}
#[allow(clippy::if_same_then_else)]
if x.ident == y {
} else if first && (*y == "core" || *y == "alloc") && x.ident == "std" {
} else {
return false;
}
first = false;
}
true
}
pub fn matches_ident(&self, ident: &syn::Ident) -> bool {
assert!(!self.0.is_empty());
self.0.iter().last().map(|s| ident == s).unwrap_or(false)
}
pub fn matches_ident_or_path(&self, path: &syn::Path) -> bool {
if path.leading_colon.is_none() && path.segments.len() == 1 {
let seg = &path.segments[0];
seg.arguments.is_empty() && self.matches_ident(&seg.ident)
} else {
self.matches(path)
}
}
}