1use syn::Item;
20
21mod error;
22mod search;
23mod selector;
24
25pub use self::error::Error;
26pub use self::selector::Selector;
27
28pub fn select(path: &str, file: &syn::File) -> Result<Vec<Item>, Error> {
37 Ok(Selector::try_from(path)?.apply_to(file))
38}
39
40#[cfg(test)]
41mod tests {
42 use syn::Item;
43
44 use super::{select, Selector};
45
46 fn sample() -> syn::File {
47 syn::parse_str(
48 "mod a {
49 mod b {
50 trait C {
51 fn d() {
52 struct E;
53 }
54 fn f(self) {
55 struct E;
56 }
57 }
58 }
59 fn b() {}
60 }",
61 )
62 .unwrap()
63 }
64
65 fn sample_with_cfg() -> syn::File {
66 syn::parse_str(
67 r#"
68 /// Outer doc
69 #[cfg(feature = "g")]
70 mod imp {
71 /// Documentation
72 #[serde(skip)]
73 #[cfg(feature = "h")]
74 pub struct H(u8);
75 }
76 #[cfg(not(feature = "g"))]
77 mod imp {
78 pub struct H(u16);
79 }"#,
80 )
81 .unwrap()
82 }
83
84 fn search_sample(path: &str) -> Vec<syn::Item> {
85 select(path, &sample()).unwrap()
86 }
87
88 fn ident(ident: &str) -> syn::Ident {
89 syn::parse_str::<syn::Ident>(ident).unwrap()
90 }
91
92 #[test]
93 fn autotraits() {
94 fn assert_send<T: Send>() {}
95 fn assert_sync<T: Sync>() {}
96 assert_send::<Selector>();
97 assert_sync::<Selector>();
98 }
99
100 #[test]
101 fn example_1() {
102 let result = search_sample("a::b::C");
103 assert_eq!(result.len(), 1);
104 if let Item::Trait(item) = &result[0] {
105 assert_eq!(item.ident, ident("C"));
106 } else {
107 panic!("Result was wrong type");
108 }
109 }
110
111 #[test]
112 fn example_2() {
113 let result = search_sample("a::b::C::d::E");
114 assert_eq!(result.len(), 1);
115 if let Item::Struct(item) = &result[0] {
116 assert_eq!(item.ident, ident("E"));
117 } else {
118 panic!("Result was wrong type");
119 }
120 }
121
122 #[test]
126 fn example_3() {
127 let result = search_sample("a::b::C::f");
128 assert_eq!(result.len(), 1);
129 if let Item::Trait(item) = &result[0] {
130 assert_eq!(item.items.len(), 1);
131 if let syn::TraitItem::Fn(item) = &item.items[0] {
132 assert_eq!(item.sig.ident, ident("f"));
133 }
134 }
135 }
136
137 #[test]
138 fn example_4() {
139 let result = search_sample("a::b");
140 assert_eq!(result.len(), 2);
141 }
142
143 #[test]
146 fn example_5() {
147 let result = select("imp::H", &sample_with_cfg()).unwrap();
148 assert_eq!(result.len(), 2);
149 if let Item::Struct(item) = &result[0] {
150 assert_eq!(item.attrs.len(), 4);
151 assert!(item.attrs[0].path().is_ident("doc"));
152 assert!(item.attrs[1].path().is_ident("cfg"));
153 assert!(item.attrs[2].path().is_ident("serde"));
154 assert!(item.attrs[3].path().is_ident("cfg"));
155 } else {
156 panic!("First result should be struct");
157 }
158
159 if let Item::Struct(item) = &result[1] {
160 assert_eq!(item.attrs.len(), 1);
161 assert!(item.attrs[0].path().is_ident("cfg"));
162 } else {
163 panic!("Second result should be struct");
164 }
165 }
166
167 #[test]
168 fn example_6() {
169 let result = search_sample("a::b::C::_::E");
170 assert_eq!(result.len(), 2);
171 }
172}