use syn::Item;
mod error;
mod search;
mod selector;
pub use self::error::Error;
pub use self::selector::Selector;
pub fn select(path: &str, file: &syn::File) -> Result<Vec<Item>, Error> {
Ok(Selector::try_from(path)?.apply_to(file))
}
#[cfg(test)]
mod tests {
use syn::Item;
use super::{select, Selector};
fn sample() -> syn::File {
syn::parse_str(
"mod a {
mod b {
trait C {
fn d() {
struct E;
}
fn f(self) {
struct E;
}
}
}
fn b() {}
}",
)
.unwrap()
}
fn sample_with_cfg() -> syn::File {
syn::parse_str(
r#"
/// Outer doc
#[cfg(feature = "g")]
mod imp {
/// Documentation
#[serde(skip)]
#[cfg(feature = "h")]
pub struct H(u8);
}
#[cfg(not(feature = "g"))]
mod imp {
pub struct H(u16);
}"#,
)
.unwrap()
}
fn search_sample(path: &str) -> Vec<syn::Item> {
select(path, &sample()).unwrap()
}
fn ident(ident: &str) -> syn::Ident {
syn::parse_str::<syn::Ident>(ident).unwrap()
}
#[test]
fn autotraits() {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<Selector>();
assert_sync::<Selector>();
}
#[test]
fn example_1() {
let result = search_sample("a::b::C");
assert_eq!(result.len(), 1);
if let Item::Trait(item) = &result[0] {
assert_eq!(item.ident, ident("C"));
} else {
panic!("Result was wrong type {:?}", &result[0]);
}
}
#[test]
fn example_2() {
let result = search_sample("a::b::C::d::E");
assert_eq!(result.len(), 1);
if let Item::Struct(item) = &result[0] {
assert_eq!(item.ident, ident("E"));
} else {
panic!("Result was wrong type {:?}", &result[0]);
}
}
#[test]
fn example_3() {
let result = search_sample("a::b::C::f");
assert_eq!(result.len(), 1);
if let Item::Trait(item) = &result[0] {
assert_eq!(item.items.len(), 1);
if let syn::TraitItem::Fn(item) = &item.items[0] {
assert_eq!(item.sig.ident, ident("f"));
}
}
}
#[test]
fn example_4() {
let result = search_sample("a::b");
assert_eq!(result.len(), 2);
}
#[test]
fn example_5() {
let result = select("imp::H", &sample_with_cfg()).unwrap();
assert_eq!(result.len(), 2);
if let Item::Struct(item) = &result[0] {
assert_eq!(item.attrs.len(), 4);
assert!(item.attrs[0].path.is_ident("doc"));
assert!(item.attrs[1].path.is_ident("cfg"));
assert!(item.attrs[2].path.is_ident("serde"));
assert!(item.attrs[3].path.is_ident("cfg"));
} else {
panic!("First result should be struct");
}
if let Item::Struct(item) = &result[1] {
assert_eq!(item.attrs.len(), 1);
assert!(item.attrs[0].path.is_ident("cfg"));
} else {
panic!("Second result should be struct");
}
}
#[test]
fn example_6() {
let result = search_sample("a::b::C::_::E");
assert_eq!(result.len(), 2);
}
}