enum-iterator-derive-0.6.0/Cargo.toml.orig010064400017500001750000000010341362257506200167020ustar0000000000000000[package] name = "enum-iterator-derive" version = "0.6.0" authors = ["Stephane Raux "] edition = "2018" description = "Procedural macro to iterate over the variants of a field-less enum" license = "MIT" homepage = "https://github.com/stephaneyfx/enum-iterator" repository = "https://github.com/stephaneyfx/enum-iterator.git" documentation = "https://docs.rs/enum-iterator-derive" keywords = ["enum", "variants", "iterator"] [lib] proc-macro = true [dependencies] proc-macro2 = "1.0.4" quote = "1.0.2" syn = "1.0.5" enum-iterator-derive-0.6.0/Cargo.toml0000644000000021401362257551400132110ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "enum-iterator-derive" version = "0.6.0" authors = ["Stephane Raux "] description = "Procedural macro to iterate over the variants of a field-less enum" homepage = "https://github.com/stephaneyfx/enum-iterator" documentation = "https://docs.rs/enum-iterator-derive" keywords = ["enum", "variants", "iterator"] license = "MIT" repository = "https://github.com/stephaneyfx/enum-iterator.git" [lib] proc-macro = true [dependencies.proc-macro2] version = "1.0.4" [dependencies.quote] version = "1.0.2" [dependencies.syn] version = "1.0.5" enum-iterator-derive-0.6.0/src/lib.rs010064400017500001750000000071461362257462300157320ustar0000000000000000// Copyright (C) 2018-2019 Stephane Raux. Distributed under the MIT license. //! Procedural macro to derive `IntoEnumIterator` for field-less enums. //! //! See crate [enum-iterator](https://docs.rs/enum-iterator) for details. #![recursion_limit = "128"] #![deny(warnings)] extern crate proc_macro; use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; use std::fmt::{Display, self}; use syn::{Ident, DeriveInput}; /// Derives `IntoEnumIterator` for field-less enums. #[proc_macro_derive(IntoEnumIterator)] pub fn into_enum_iterator(input: proc_macro::TokenStream) -> proc_macro::TokenStream { derive(input).unwrap_or_else(|e| e.to_compile_error()).into() } fn derive(input: proc_macro::TokenStream) -> Result { let ast = syn::parse::(input)?; if !ast.generics.params.is_empty() { return Err(Error::GenericsUnsupported.with_tokens(&ast.generics)); } let ty = &ast.ident; let vis = &ast.vis; let ty_doc = format!("Iterator over the variants of {}", ty); let iter_ty = Ident::new(&(ty.to_string() + "EnumIterator"), Span::call_site()); let variants = match &ast.data { syn::Data::Enum(e) => &e.variants, _ => return Err(Error::ExpectedEnum.with_tokens(&ast)), }; let arms = variants.iter().enumerate() .map(|(idx, v)| { let id = &v.ident; match v.fields { syn::Fields::Unit => Ok(quote! { #idx => #ty::#id, }), _ => Err(Error::ExpectedUnitVariant.with_tokens(v)), } }) .collect::, _>>()?; let nb_variants = arms.len(); let tokens = quote! { #[doc = #ty_doc] #[derive(Clone, Copy, Debug)] #vis struct #iter_ty { idx: usize, } impl ::core::iter::Iterator for #iter_ty { type Item = #ty; fn next(&mut self) -> ::core::option::Option { let id = match self.idx { #(#arms)* _ => return ::core::option::Option::None, }; self.idx += 1; ::core::option::Option::Some(id) } fn size_hint(&self) -> (usize, ::core::option::Option) { let n = #nb_variants - self.idx; (n, ::core::option::Option::Some(n)) } } impl ::core::iter::ExactSizeIterator for #iter_ty {} impl ::core::iter::FusedIterator for #iter_ty {} impl ::enum_iterator::IntoEnumIterator for #ty { type Iterator = #iter_ty; const VARIANT_COUNT: usize = #nb_variants; fn into_enum_iter() -> Self::Iterator { #iter_ty { idx: 0 } } } }; let tokens = quote! { const _: () = { #tokens }; }; Ok(tokens) } #[derive(Debug)] enum Error { ExpectedEnum, ExpectedUnitVariant, GenericsUnsupported, } impl Error { fn with_tokens(self, tokens: T) -> syn::Error { syn::Error::new_spanned(tokens, self) } } impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::ExpectedEnum => f.write_str("IntoEnumIterator can only be derived for enum types"), Error::ExpectedUnitVariant => f.write_str("IntoEnumIterator can only be derived for enum types with unit \ variants only"), Error::GenericsUnsupported => f.write_str("IntoEnumIterator cannot be derived for generic types"), } } } enum-iterator-derive-0.6.0/.cargo_vcs_info.json0000644000000001121362257551400152100ustar00{ "git": { "sha1": "293f7b84794341bf873d84d3654c3cda0441d594" } }