Code Monkey home page Code Monkey logo

strum's Introduction

Strum

Build Status Build status Latest Version Rust Documentation Crates.io Crates.io

Strum is a set of macros and traits for working with enums and strings easier in Rust.

Compatibility

Strum is currently compatible with versions of rustc >= 1.56.1. Pull Requests that improve compatibility with older versions are welcome. The project goal is to support a rust version for at least 2 years after release and even longer is preferred since this project changes slowly.

Including Strum in Your Project

Import strum and strum_macros into your project by adding the following lines to your Cargo.toml. Strum_macros contains the macros needed to derive all the traits in Strum.

[dependencies]
strum = "0.26"
strum_macros = "0.26"

# You can also use the "derive" feature, and import the macros directly from "strum"
# strum = { version = "0.26", features = ["derive"] }

Strum Macros

Strum has implemented the following macros:

Macro Description
EnumString Converts strings to enum variants based on their name.
Display Converts enum variants to strings
FromRepr Convert from an integer to an enum.
AsRefStr Implement AsRef<str> for MyEnum
IntoStaticStr Implements From<MyEnum> for &'static str on an enum
EnumIter Creates a new type that iterates of the variants of an enum.
EnumProperty Add custom properties to enum variants.
EnumMessage Add a verbose message to an enum variant.
EnumDiscriminants Generate a new type with only the discriminant names.
EnumCount Add a constant usize equal to the number of variants.
VariantArray Adds an associated VARIANTS constant which is an array of all enum discriminants
VariantNames Adds an associated VARIANTS constant which is an array of discriminant names
EnumTable Experimental, creates a new type that stores an item of a specified type for each variant of the enum.

Contributing

Thanks for your interest in contributing. Bug fixes are always welcome. If you are interested in implementing or adding a macro, please open an issue first to discuss the feature. I have limited bandwidth to review new features.

The project is divided into 3 parts, the traits are in the /strum folder. The procedural macros are in the /strum_macros folder, and the integration tests are in /strum_tests. If you are adding additional features to strum or strum_macros, you should make sure to run the tests and add new integration tests to make sure the features work as expected.

Debugging

To see the generated code, set the STRUM_DEBUG environment variable before compiling your code. STRUM_DEBUG=1 will dump all of the generated code for every type. STRUM_DEBUG=YourType will only dump the code generated on a type named YourType.

Name

Strum is short for STRing enUM because it's a library for augmenting enums with additional information through strings.

Strumming is also a very whimsical motion, much like writing Rust code.

strum's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

strum's Issues

EnumProperty: opting-in stronger guarantees on properties

Currently deriving EnumProperty results in a bunch of get*() -> Option<*>. This works quite well in general, but it moves some property checking to runtime option-handling.

What I'd like to see provided in this crate is some way of opting-in to stronger guarantees and typing of properties, such that I could:

  • annotate the enum to require that all variants declare some specific property
  • either annotate or infer the type of this mandatory property
  • generate specific getter for each mandatory property, such that there is a single get_prop() -> PropType generated

The usestory for this is: complex enums declarations (with attributes) can become quite long and some variants can end up with missing prop-attributes or with copy-paste type mistakes. Those would only be catched when unwrapping the Option at runtime, but the compiler should be able to sanity-check this at buildtime. Also it would make the getter more specifically named and remove the needs of Option wrapping.

Some hypotetical syntax (but feel free to design your one discarding this) could be:

#[derive(EnumProperty)]
#[strum(props(room: i32))]
enum Class {
    #[strum(props(teacher="foo", room=101))]
    History,
    #[strum(props(room=2))]
    Mathematics,
    #[strum(props(room=-1))]
    Science,
}

fn main() {
    let history = Class::History;
    assert_eq!(101, history.get_room());
}

Where adding a variant without the room prop or with a non-matching type would fail type-checking / compilation.

v0.14.0 missing from changelog

This project does have a CHANGELOG.md file (๐Ÿ‘), but it seems like the new v0.14.0 release is missing from it. What were the changes that went into that release? Were there any breaking changes?

Impl back from EnumDiscriminant

The derive for EnumDiscriminant is helpful, but it doesn't provide a way to convert back to the original enum whose variants it enumerates. Is this something that can be implemented?

How do I add docstrings to discriminants?

First of all, thanks for this crate!

I'm refactoring some code to use the discriminants and would like to keept the documentation and doctests on the discriminant enum. Is there any way I can do that?

FromStr derive could support setting the error type

When you derive on an enum, sometimes you want to implement some From<XXXNotFound> for some other error types, with maybe more explicit messages. It would be great if we could have an attribute that enables us to set the function that would be used to build the error from the original &str.

e.g.

#[derive(EnumString)]
#[strum(parse_err_ty = "SomeEnumNotFound", parse_err_fn = "some_enum_not_found_err")]
pub enum SomeEnum {
	A,
	B,
}

pub struct SomeEnumNotFound;
fn some_enum_not_found_err(_not_found: &str) -> SomeEnumNotFound { SomeEnumNotFound }

generating

impl FromStr for SomeEnum {
    type Err = SomeEnumNotFound;
    fn from_str(s: &str) -> Result<SomeEnum, Self::Err> {
        match s {
            "A" => A,
            "B" => B,
            other => some_enum_not_found_err(other),
        }
    }
}

If parse_err_fn is not specified but parse_err_ty is, we could fallback on From<strum::ParseError>.

Interaction between serde and strum that results in a compiler error

Hi!

I've noticed that using strum's derive EnumDiscriminants with some serde variant attributes, results in a compiler error.

I'm not sure of this is an issue in strum, in serde, or both.

Here's a program to reproduce the issue:

Cargo.toml

[dependencies]
serde = { version = "1.0", features = ["derive"] }
strum = "0.16.0"
strum_macros = "0.16.0"

src/main.rs

extern crate strum;
#[macro_use] extern crate strum_macros;
extern crate serde;

use std::str::FromStr;

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug, EnumDiscriminants)]
#[serde(tag = "type")]
enum Message {
    #[serde(rename = "request" )]
    Request { id: String, method: String, params: u8 },
    #[serde(rename = "response" )]
    Response { id: String, result: u8 },
}

fn main() {
    println!("Hello, world!");
}

Compiler error

error[E0658]: the attribute `serde` is currently unknown to the compiler and may have meaning added to it in the future
  --> src/main.rs:12:5
   |
12 |     #[serde(rename = "request" )]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: for more information, see https://github.com/rust-lang/rust/issues/29642

error[E0658]: the attribute `serde` is currently unknown to the compiler and may have meaning added to it in the future
  --> src/main.rs:14:5
   |
14 |     #[serde(rename = "response" )]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: for more information, see https://github.com/rust-lang/rust/issues/29642

warning: unused import: `std::str::FromStr`
 --> src/main.rs:5:5
  |
5 | use std::str::FromStr;
  |     ^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.

Additional info

The program compiles successfully if the lines #[serde(rename = "response" )] are removed.

IntoEnumIterator: consider using standard IntoIterator instead

It would be nice if strum could incapsulate a bit more its implementation details.

In particular, I'd like to avoid having strum::IntoEnumIterator to be imported by all consumers, and instead use the IntoIterator one from stdlib.
That one however is a consuming method, so I'm not sure if it can be transparently adopted. An alternative would be to drop the trait completely and just expose a naked iter() like most collection types do.

EnumString: implement ToString/Display as well?

I was briefly looking at this crate, and I think I would love to see an automatic to_string() implementation and some way to link it to the current attributes-based approach employed for from_string(). This would allow for roundtrips Enum <-> String.

I'm actually thinking about something similar to serde ones plus additional aliases:

#[derive(EnumString)]
enum Color {
    #[strum(rename="blue",alias="b")]
    Blue,
    ...
}

impl std::str::FromStr for Color {
    fn from_str(s: &str) -> ::std::result::Result<Color, Self::Error> {
        match s {
               "blue" | "b" => ::std::result::Result::Ok(Color::Blue),
               ...
        }
    }
}

impl fmt::Display for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
               Color::Blue => write!(f, "blue"),
               ...
        }
    }
}

There are also a bunch more interesting methods in https://docs.rs/enum_derive/0.1.7/enum_derive/#overview.

0.15 breaks Display

The following piece of code:

#[macro_use]
extern crate strum_macros;

#[derive(Clone, Copy, Display, Debug, Serialize)]
#[strum(serialize_all = "snake_case")]
pub enum DataName {
    SecretHash,
    Expiry,
    RedeemIdentity,
    RefundIdentity,
    TokenQuantity,
    TokenContract,
}

Compiles with 0.14.0 but does not compile with 0.15.0:

error[E0658]: The attribute `strum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
  --> vendor/blockchain_contracts/src/lib.rs:16:3
   |
16 | #[strum(serialize_all = "snake_case")]
   |   ^^^^^
   |
   = help: add #![feature(custom_attribute)] to the crate attributes to enable
error: cannot find derive macro `Display` in this scope
  --> vendor/blockchain_contracts/src/lib.rs:15:23
   |
15 | #[derive(Clone, Copy, Display, Debug, Serialize)]
   |    

May I suggest to move the readme examples to rust-docs to avoid this kind of issue?

Please update proc_macro2, quote, and syn to v1.0

hello!

we're currently updating proc-macro2, quote, and syn in Debian (which all recently reached 1.0). An update for strum-macros with those versions would be great (we're also able to cherrypick a patch if needed).

Thanks!

Add EnumCount derive

I wrote this proc-macro because I needed it (for mapping Enum cases from different enums to Vec regions, making the Vec len equal to the combined number of all cases) and I think it would make sense to include it in this crate, because it already contains many useful derives for enums.
https://github.com/Boscop/enum-count/blob/master/src/lib.rs
https://github.com/Boscop/enum-count-derive/blob/master/src/lib.rs

It allows stuff like this:

#[derive(EnumCount)] enum Aa { }

#[derive(EnumCount)]
enum Bb { B0 = AA_COUNT as _ }

#[repr(u8)]
#[derive(EnumCount)]
enum Cc { C0 = AA_COUNT as _, C1 = BB_COUNT as _ }

#[repr(usize)]
#[derive(EnumCount)]
enum Dd { D0 = AA_COUNT, D1 = BB_COUNT, D2 = CC_COUNT }

fn main() {
	println!("{} {} {} {}", Aa::count(), BB_COUNT, Cc::count(), DD_COUNT);
}

(The constant is necessary for it to be used in other enums and static array lens etc.)

Derived Display doesn't handle width and alignment parameters

For struct like:

#[derive(Display)]
enum Type {
    One,
    Two,
}

The call:

println!("_ {:<20} _", Type::One);

Will print:

_ One _

But this expected:

_ One                 _

The workaround today only to convert it to string first:

println!("_ {:<20} _", Type::One.as_ref()); // and derive `AsRefStr` for enum needed

Implement From<&str> instead of FromStr for enums with lifetimes

FromStr doesn't support lifetimes, and I'd like the following to be possible:

#[derive(Debug, PartialEq, Eq, Clone, Copy, strum_macros::AsRefStr, strum_macros::EnumString)]
pub enum ChunkType<'a> {
    #[strum(to_string = "nMC")]
    MChat,
    #[strum(to_string = "nM")]
    MPlayer,
    #[strum(to_string = "nMR")]
    MRequest,
    #[strum(to_string = "nM?")]
    MServerInfo,
    #[strum(to_string = "nU")]
    UUpdate,
    #[strum(to_string = "\r\n")]
    Eof,
    #[strum(to_string = "nH")]
    HHead,
    #[strum(default = "true")]
    Unknown(&'a str),
}

Publish v0.16.0

Hi,

Would be awesome if you could publish a v0.16.0 of Strum to https://crates.io/crates/strum, as the latest version there is v0.15.0 from March, which for example doesn't have EnumVariantNames (#56)

Right now I have to do this to get EnumVariantNames in my project:

[dependencies]
strum = { git = "https://github.com/Peternator7/strum", rev = "efed58502a40ac101691068bbc6c20a0b351f3fd" }
strum_macros = { git = "https://github.com/Peternator7/strum", rev = "efed58502a40ac101691068bbc6c20a0b351f3fd" }

(Also would be nice with tags in Github that corresponds to the releases on Crates.io.)

Thanks!

Naming problems

I wonder how you manage the non-descriptive names like as_static, as_ref, when you have an enum that, e.g. describes a state:

enum MyState {
    Position1(i32),
    GameOver(String),
}

Having my_state.as_ref() or my_state.as_static() looks odd to me when I really want to express my_state.as_variant_name(). Currently, I have to write a 4-line wrapper around as_static just to make my API sane, but I still have a confusing AsStaticRef implementation in the documentation.

This is a small papercut, but I still want to bring it in.

I would prefer having AsEnumVariantName trait with as_enum_variant_name or as_variant_name method.

Join members of enum

Given that I have this enum:

enum SpecialSeries {
    DA,
    KT,
    LD,
}

Now I want to build this string

"DA|KT|LD"

in order to use as pattern for RegEx. How should I code with strum? (I don't write Rust often and always forget things when I try to learn Rust again).

Thank you.

IntoEnumIterator should have a constraint on Iterator: Iterator<Item=Self>

IntoEnumIterator does not have a constraint on Iterator: Iterator<Item=Self>.
When writing generic code on any IntoEnumIterator, it forces us to write the very verbose:

where
	<Self as IntoEnumIterator>::Iterator: Iterator<Item = Self>,

though that behaviour could be enforced as it is documented on the trait.

We could avoid having to write this by adding an Iterator<Item=Self> bound on the associated type Iterator of IntoEnumIterator.

`serialize_all` should be "as-is"

rename_all from serde accepts kebab-case, camelCase, PascalCase, etc. The option string is just written in what itself representing to.

But serialize_all accepts all options in snake case, like kebab_case or shouty_snake_case, which can be sometimes misleading.

I think we should accept and prefer serde-like option string, while the snake case options can still be used for compatibility, maybe with a warning.

Reverse/DoubleEnded EnumIter

It would be nice to be able to iterate over enums in reverse order.

Currently I have to use the workaround my_enum::iter().collect::<Vec<_>>().iter().rev(), which is quite ugly and probably less performant.

This could be implemented by making the IntoEnumIter::iter function return a DoubleEndedIterator to allow code like this:

#[derive(EnumIter)]
enum Colors {Red, Green, Blue}

use strum::IntoEnumIterator;
for color in Colors::iter().rev() {
    // Do something with color.
}

This approach might incur a runtime cost, because we would have to add another field to the iterator struct (a second index for next_back similar to the existing idx) even if the user does not call next_back.

Another possible way to implement this is to add a new method, that returns a reverse or double-ended iterator.

Are you interested in adding this functionality?

Does not compile on rust 1.36.0

Although the docs state compatibility with 1.31.0

error[E0658]: use of unstable library feature 'iter_nth_back'
   --> src/main.rs:139:75
    |
139 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, EnumIter)]
    |                                                                           ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/56995

error: aborting due to previous error

Conflict with `display_derive`

The Display procedural macro unfortunately conflicts with @withoutboats' display_derive procedural macro. In some code I'm working with on a personal project, the following will compile when #[macro_use]ing only display_derive, but not in conjunction with strum_derive:

#[derive(Clone, Debug, Deserialize, Display, Eq, Hash, PartialEq, Serialize)]
#[display(fmt = "{}", _0)]
pub struct MessageId(pub String);

Both of these crates are great additions to the ecosystem, in my opinion. It's a shame that we don't have macros as first-class items yet and that I have to choose between them. Perhaps disabling Display with a feature flag would be best for now?

EDIT: It's also possible to use the right crate's definition by making the desired derive be imported LAST...but that's a hacky workaround.

EnumIter construction

As it currently is, Strum's EnumIterator trait only allows for the construction of enum iterators from the first variant, which makes it horribly inefficient (relatively speaking) to perform incremental iteration of enum variants. A means of constructing this iterator so it starts from an existing enum would resolve this.

FromIndex and ToIndex traits

I'm interested in porting the FromIndex and ToIndex traits from enum_traits to this crate.

However I only care about the from_index and index methods. The other methods don't seem useful?

My reasoning is that enum_traits is unmaintained and its functionality seems similar enough to this crate.
What are your thoughts? Is this within scope of the project?

Can enum::count() be a const function?

When EnumCount was introduced, there was a comment that the count() function could be const once the required feature get stabilized in Rust. It seems to me it is possible now, but I'm not a Rust expert yet, so I could be wrong. What is your opinion of this?

As a side effect, this could get rid of the X _COUNT constants polluting the public namespace, but I don't know if you'd want to remove them due to backwards compatibility. However, according to semver, version 0.x.y does not provide any guarantees, so the users should not have any assumptions anyway.

EnumProperty other than String?

When will it be possible to use EnumProperty with other types than String?
Are only literals supported or full expressions? :)

Provide means to specify error string when matching variant is not found

Right now --when no matching variant is found-- (parsing a string into an enum using the derived from_str) a constant string error is returned saying "Matching variant not found". There are two improvements that can be done on this:

  • Better default: A better default would probably be something like "expected 'string1', 'string2', 'string3' or 'string4'". Even though it costs to iterate over the options, it doesn't matter, because it would only happen when no valid string is found.

  • Custom error: The user should be able to specify a custom error message, something like:

#[derive(EnumString)]
#[strum(onerror="We like you, but can't understand what you wrote, please use 'string1' or 'string2'")
enum Foo {
   #[strum(serialize="string1")]
   Option1,
   #[strum(serialize="string2")]
   Option2,
}

** special token: You could even provide a special token for the onerror keyword so that the user doesn't have to repeat the options all the time. Something like onerror="We like you, but can't understand what you wrote, please use {opts}".

Convert isize to enum variant

Sometimes we need to convert isize to an enum variant with explicit discriminator.
enum/c_like
For example, high level API converts error code to an error enum variant. The feature will be useful when it comes to unsafe and FFI.

The solution is to implement a proc macro like:
proc_macro_derive(EnumFromIsize)

The generated code will look like:

impl TryFrom<isize> for MyEnum {
    type Error = StrumCustomError;
    fn try_from(u: isize) -> Result<MyEnum, StrumCustomError> {
        match u {
            // ......
        }
    }
}

typo in docs

strum/strum/src/lib.rs

Lines 113 to 117 in b6e4e66

//! // It's simple to iterate over the variants of an enum.
//! fn debug_colors() {
//! let red = Color::Red;
//! assert_eq!(String::from("redred"), red.to_string());
//! }

Also the same type is in the Readme.

how to round trip Display and EnumString with default="true"

I have some default variant that contains a string, like:

#[derive(Display, EnumString)]
FooEnum {
  #[strum(default="true")]
  Bar(String)
}

but if i do:

FooEnum::Bar("baz".into()).to_string();

i get "Bar" not "baz" so then there's no way to round trip it back into the original FooEnum

EnumString documentation lacking example

In the documentation and Wiki for EnumString , there is
//The generated code will look like:
but there is no actual code example how to use it.

Something like this:

use std::str::FromStr;  
let color_str="Red";  
let color_variant = Color ::from_str(color_str).unwrap();
assert!(Color:Red, color_variant);

Why is the documentation/examples using the old syntax:

extern crate strum;  
#[macro_use] extern crate strum_macros;

instead of the new:

use strum;  
use strum_macros

Attribute to format field names

I would like to be able to do something like this

#[derive(Display)]
#[strum("series.{}", serialize_all = "snake_case")]
struct Series {
    Media
}

assert_eq!(Series::Media.to_string(), "series.media".to_string());

The attribute could also look like this

#[strum(format = "series.{}", serialize_all = "snake_case")]

The implementation would be relatively simple (I think?):

use syn::LitStr;

// parse this from the attribute:
let format_string = "series.{}".to_string();
// the serialized field name
let field_name = "media".to_string();

let lit_str = LitStr::new(&format_string.replace("{}", &field_name), Span::call_site());

quote {
    impl ::std::fmt::Display for Series {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            match &self {
                Self::Media => f.write_str(#lit_str),
            }
        }
    }
}

ToString: implement `Display`, std doc says "`ToString` shouldn't be implemented directly"

Rustdoc for ToString says:

ToString shouldn't be implemented directly: Display should be implemented instead, and you get the ToString implementation for free.

So derive(ToString) should implement std::fmt::Display instead of std::string::ToString (and by this, std::string::ToString would be automatically implemented).
Then derive(Display) or some other appropriate names would be preferable to derive(ToString).

This may be breaking changes (possibly rename ToString and to_string), but automatic derive for Display will be very useful.

Release next version

Hiya! Thanks for this awesome crate ๐ŸŽ‰.
There are a number of fixes in master that help me along my quest โš”๏ธ.
Please could you release the crate ๐Ÿ“ฆ, or is there something that must first be done (like that open PR)?

Derive enum with variants without fields

EnumIter and EnumString both work by using Default::default() values for any fields on an enum variant. I have a use case where I want to match on the enum's discriminant, but the fields are !Default.

To do this, I propose a #[derive(EnumDiscriminants)] as well as the attribute #[strum_discriminants(derive(..))], which will have the following effect:

struct NonDefault;

#[derive(EnumDiscriminants)]
#[strum_discriminants(
    name(HelloVariants),
    derive(EnumString, EnumIter),
    strum(serialize_all = "snake_case")
)]
enum Hello {
    Variant0,
    Variant1(NonDefault),
    Variant2 { a: NonDefault },
}

// produces:
/// Auto-generated discriminant variants for the `Hello` enum.
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumString, EnumIter)]
#[strum(serialize_all = "snake_case")]
enum HelloVariants {
    Variant0,
    Variant1,
    Variant2,
}

impl From<Hello> for HelloVariants {
    fn from(val: Hello) -> HelloVariants {
        match val {
            Hello::Variant0 => HelloVariants::Variant0,
            Hello::Variant1(..) => HelloVariants::Variant1,
            Hello::Variant2 { .. } => HelloVariants::Variant2,
        }
    }
}

impl<'_enum> From<&'_enum Hello> for HelloVariants {
    fn from(val: &'_enum Hello) -> HelloVariants {
        match *val {
            Hello::Variant0 => HelloVariants::Variant0,
            Hello::Variant1(..) => HelloVariants::Variant1,
            Hello::Variant2 { .. } => HelloVariants::Variant2,
        }
    }
}

Help with 2018 edition

Using strum with rust 2018 probably needs a use strum<something>::strum; because by default this error appears:

error[E0658]: The attribute `strum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
 --> /home/xav/lfgt/target/debug/build/lfgt-3925bf91df78c23d/out/equipments.rs:3:5
  |
3 |     #[strum(serialize = "agt")]
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Would it be possible to add the remedy to the README.md ?

I way to provide my own implementation.

Maybe I'm just dumb, but is there a way to do something like:

enum Compression {
Lz4,
Gzip(u8),
}

Compression::Gzip(9).to_string() # returns gzip-9
Compression::from_str("gzip-2") # returns Compression::Gzip(2)

Cannot use full-qualified path to trait inside `#[strum_discriminants(derive())]`

When trying to use full-qualified paths for the custom derive, none of the attributes are applied.

For example:

#[allow(dead_code)]
#[derive(Debug, Eq, PartialEq, strum_macros::EnumDiscriminants)]
#[strum_discriminants(name(SplitAttributesBoo), derive(strum_macros::Display))]
#[strum_discriminants(derive(strum_macros::EnumIter))]
enum SplitAttributes {
    Variant0(bool),
    Variant1(i32),
}

I digged a bit into the code and it actually looks like syn doesn't report the full path in that case. I googled around a bit and found a similar problem here: rust-lang/rust#55168

But not sure how relevant that actually is.
I created a PR that reproduces the issue here: #54.

Catchall for EnumString

Is there any way to provide a "catchall" option for EnumString that will store the parsed string into a variant?

Eg:

enum Fruit {
    Strawberry,
    Banana,
    Other(String),
}

Thanks!

Minor version bump needed?

I noticed that the EnumVariantNames is shown in the README (and it is pretty useful!), but it is not available on the last release. Could a minor version bump be worth in order to use this feature in a stable release?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.