Skip to content

Commit

Permalink
feat: disallow custom discriminants
Browse files Browse the repository at this point in the history
  • Loading branch information
SpecificProtagonist authored and Pscheidl committed Jan 15, 2023
1 parent 3eed022 commit 5925a72
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 58 deletions.
3 changes: 2 additions & 1 deletion enum-collections-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "enum-collections-macros"
version = "0.3.0"
version = "0.4.0"
edition = "2021"

description = "Macros to make EnumCollections easy to use"
Expand All @@ -18,3 +18,4 @@ proc-macro = true

[dependencies]
syn = "1.0"
quote = "1.0"
69 changes: 16 additions & 53 deletions enum-collections-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,32 @@
use proc_macro::TokenStream;
use syn::{
parse_macro_input, DeriveInput,
__private::{quote::quote, ToTokens},
};
use quote::{quote, quote_spanned};
use syn::{parse_macro_input, spanned::Spanned, DeriveInput};

/// Creates `enum_map::Enumerated` implementation for the underlying Enum.
/// Also derives Copy and Clone.
#[proc_macro_attribute]
#[deprecated(since = "0.4.0", note = "Use #[derive(Enumerated)] instead")]
pub fn enum_collections(_args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_derive(Enumerated)]
pub fn derive_enum_collections(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let generics = &input.generics;
let name = &input.ident;
let enum_count: usize = match &input.data {
syn::Data::Enum(en) => en.variants.iter().count(),
syn::Data::Struct(_) | syn::Data::Union(_) => {
return quote! {
#input
compile_error!("The `enummap` macro only supports enums.");
let syn::Data::Enum(en) = input.data else {
return quote_spanned! {
input.span() => compile_error!("The `Enumerated` macro only supports enums.");
}
.to_token_stream()
.to_token_stream()
.into();
}
};

let output = quote! {
#input

impl #generics Enumerated for #name #generics {

fn position(self) -> usize {
self as usize
}

const fn len() -> usize{
#enum_count
}

}
};
TokenStream::from(output.to_token_stream())
}
let enum_count = en.variants.iter().count();

/// Creates `enum_map::Enumerated` implementation for the underlying Enum.
/// Also derives Copy and Clone.
#[proc_macro_derive(Enumerated)]
pub fn derive_enum_collections(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let generics = &input.generics;
let name = &input.ident;
let enum_count: usize = match &input.data {
syn::Data::Enum(en) => en.variants.iter().count(),
syn::Data::Struct(_) | syn::Data::Union(_) => {
return quote! {
#input
compile_error!("The `enummap` macro only supports enums.");
for variant in en.variants {
if let Some((_, discriminant)) = variant.discriminant {
return quote_spanned! {
discriminant.span() => compile_error!("`Enumerated` doesn't support discriminants");
}
.to_token_stream()
.to_token_stream()
.into();
}
};
}

let output = quote! {
quote! {
impl #generics Enumerated for #name #generics {

fn position(self) -> usize {
Expand All @@ -75,6 +38,6 @@ pub fn derive_enum_collections(input: TokenStream) -> TokenStream {
}

}
};
TokenStream::from(output.to_token_stream())
}
.into()
}
2 changes: 1 addition & 1 deletion enum-collections/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ categories = ["data-structures"]
documentation = "https://docs.rs/enum-collections"

[dependencies]
enum-collections-macros = "0.2.0"
enum-collections-macros = "0.4.0"

[dev-dependencies]
criterion = "0.4.0"
Expand Down
3 changes: 2 additions & 1 deletion enum-collections/src/enummap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::Enumerated;
/// Using `get` and `insert` functions.
///
/// ```
/// use enum_collections::{enum_collections, EnumMap, Enumerated};
/// use enum_collections::{EnumMap, Enumerated};
/// #[derive(Enumerated)]
/// enum Letter {
/// A,
Expand Down Expand Up @@ -111,6 +111,7 @@ mod tests {
A,
B,
}

#[test]
fn new_all_none() {
let enum_map = EnumMap::<Letter, i32>::new();
Expand Down
2 changes: 1 addition & 1 deletion enum-collections/src/enumtable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::Enumerated;
///
/// Using get and insert functions.
/// ```
/// use enum_collections::{enum_collections, EnumTable, Enumerated};
/// use enum_collections::{EnumTable, Enumerated};
/// #[derive(Enumerated)]
/// enum Letter {
/// A,
Expand Down
1 change: 0 additions & 1 deletion enum-collections/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ mod enumtable;
pub use crate::enumerated::Enumerated;
pub use crate::enummap::EnumMap;
pub use crate::enumtable::EnumTable;
pub use enum_collections_macros::enum_collections;
pub use enum_collections_macros::Enumerated;

#[cfg(test)]
Expand Down

0 comments on commit 5925a72

Please sign in to comment.