#![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)
}
}
}