auto_enums_core 0.1.2

This library provides an attribute macro for to allow multiple return types by automatically generated enum.
Documentation
use smallvec::SmallVec;

use syn::{
    visit::{self, Visit},
    *,
};

use crate::utils::*;

use super::*;

pub(super) fn collect_impl_traits(ty: &Type) -> Option<SmallVec<[Path; 4]>> {
    let mut traits = SmallVec::new();
    ImplTraits::new(&mut traits).visit_type(ty);

    if traits.is_empty() {
        None
    } else {
        Some(traits)
    }
}

struct ImplTraits<'a> {
    traits: &'a mut SmallVec<[Path; 4]>,
}

impl<'a> ImplTraits<'a> {
    fn new(traits: &'a mut SmallVec<[Path; 4]>) -> Self {
        ImplTraits { traits }
    }
}

impl<'a, 'ast> Visit<'ast> for ImplTraits<'a> {
    fn visit_type_impl_trait(&mut self, ty: &'ast TypeImplTrait) {
        visit::visit_type_impl_trait(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",
    "Deref",
    "DerefMut",
    "Index",
    "IndexMut",
    "Fn",
    "FnMut",
    "FnOnce",
    "RangeBounds",
    "AsRef",
    "AsMut",
    "Iterator",
    "DoubleEndedIterator",
    "ExactSizeIterator",
    "FusedIterator",
    "TrustedLen",
    "Extend",
    "Future",
    "Read",
    "io::Read",
    "BufRead",
    "io::BufRead",
    "Write",
    "io::Write",
    "Seek",
    "io::Seek",
    "Error",
    "error::Error",
    "Debug",
    "fmt::Debug",
    "Display",
    "fmt::Display",
    "fmt::Binary",
    "fmt::LowerExp",
    "fmt::LowerHex",
    "fmt::Octal",
    "fmt::Pointer",
    "fmt::UpperExp",
    "fmt::UpperHex",
    "fmt::Write",
];

pub(super) fn parse_impl_traits(args: &mut Stack<Arg>, traits: SmallVec<[Path; 4]>) {
    traits.into_iter().map(|t| t.into()).for_each(|t| {
        if !args.contains(&t) && TRAITS.contains(&&*t.to_trimed_string()) {
            args.push(t)
        }
    });
}