PackageTrack
Sign in Get early access

strum

Helpful macros for working with enums and strings

0.28.0 588M downloads/mo #164 most downloaded on crates.io Peternator7/strum

What this package is like to depend on

Last release 6 months ago

22 Feb 2026

Release timing varies

gaps range from 8 days to 12 months

Most releases are documented

notes for 28 of 39 stable releases

1 version withdrawn

withdrawn after publishing

10 years old

40 releases · first in 2017

1 release in the last 12 months

see the full history below

Release timeline

40 releases · Feb 2017 to Feb 2026
2018 2019 2020 2021 2022 2023 2024 2025 2026
Release Pre-release Withdrawn

Releases

latest 40
  1. 0.28.0 22 Feb 2026
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.27.2...v0.28.0

    Open source →
    Release notes
    • #461: Allow any kind of passthrough attributes on EnumDiscriminants.

      • Previously only list-style attributes (e.g. #[strum_discriminants(derive(...))]) were supported. Now path-only (e.g. #[strum_discriminants(non_exhaustive)]) and name/value (e.g. #[strum_discriminants(doc = "foo")]) attributes are also supported.
    • #462: Add missing #[automatically_derived] to generated impls not covered by #444.

    • #466: Bump MSRV to 1.71, required to keep up with updated syn and windows-sys dependencies. This is a breaking change if you're on an old version of rust.

    • #469: Use absolute paths in generated proc macro code to avoid potential name conflicts.

    • #465: Upgrade phf dependency to v0.13.

    • #473: Fix cargo fmt / clippy issues and add GitHub Actions CI.

    • #477: strum::ParseError now implements core::fmt::Display instead std::fmt::Display to make it #[no_std] compatible. Note the Error trait wasn't available in core until 1.81 so strum::ParseError still only implements that in std.

    • #476: Breaking Change - EnumString now implements From<&str> (infallible) instead of TryFrom<&str> when the enum has a #[strum(default)] variant. This more accurately reflects that parsing cannot fail in that case. If you need the old TryFrom behavior, you can opt back in using parse_error_ty and parse_error_fn:

      #[derive(EnumString)]
      #[strum(parse_error_ty = strum::ParseError, parse_error_fn = make_error)]
      pub enum Color {
          Red,
          #[strum(default)]
          Other(String),
      }
      
      fn make_error(x: &str) -> strum::ParseError {
          strum::ParseError::VariantNotFound
      }
      
    • #431: Fix bug where EnumString ignored the parse_err_ty attribute when the enum had a #[strum(default)] variant.

    • #474: EnumDiscriminants will now copy default over from the original enum to the Discriminant enum.

      #[derive(Debug, Default, EnumDiscriminants)]
      #[strum_discriminants(derive(Default))] // <- Remove this in 0.28.
      enum MyEnum {
          #[default] // <- Will be the #[default] on the MyEnumDiscriminant
          #[strum_discriminants(default)] // <- Remove this in 0.28
          Variant0,
          Variant1 { a: NonDefault },
      }
      
    Open source →
  2. 0.27.2 19 Jul 2025
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.27.1...v0.27.2

    Open source →
    Release notes
    • #141: Adding support for doc comments on EnumDiscriminants generated type.

      • The doc comment will be copied from the variant on the type itself.
    • #435:allow discriminants on empty enum.

    • #443: Change enum table callbacks to FnMut.

    • #444: Add #[automatically_derived] to the impls by @dandedotdev in https://github.com/Peternator7/strum/pull/444

      • This should make the linter less noisy with warnings in generated code.
    • #440: Implement a suffix attribute for serialization of enum variants.

      #[derive(strum::Display)]
      #[strum(suffix=".json")]
      #[strum(serialize_all="snake_case")]
      enum StorageConfiguration {
        PostgresProvider,
        S3StorageProvider,
        AzureStorageProvider,
      }
      
      fn main() {
        let response = SurveyResponse::Other("It was good".into());
        println!("Loading configuration from: {}", StorageConfiguration::PostgresProvider);
        // prints: Loaded Configuration from: postgres_provider.json
      }
      
    • #446: Drop needless rustversion dependency.

    Open source →
  3. 0.27.1 17 Feb 2025
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.27.0...v0.27.1

    Open source →
    Release notes
    • #414: Fix docrs build error.

    • #417: Mention parse_error_ty and parse_error_fn that had been left out of the docs accidentally.

    • #421#331: Implement #[strum(transparent)] attribute on IntoStaticStr, Display and AsRefStr that forwards the implmenentation to the inner value. Note that for static strings, the inner value must be convertible to an &'static str.

      #[derive(strum::Display)]
      enum SurveyResponse {
        Yes,
        No,
        #[strum(transparent)]
        Other(String)
      }
      
      fn main() {
        let response = SurveyResponse::Other("It was good".into());
        println!("Question: Did you have fun?");
        println!("Answer: {}", response);
        // prints: Answer: It was good
      }
      
    Open source →
  4. 0.27.0 08 Feb 2025
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.26.3...v0.27.0

    Open source →
    Release notes

    Highlights

    • #407: Display is now correctly derived in [no_std] projects.
    • #402: EnumIter now implements Send + Sync
    • #400: EnumTryAs now handles attributes on variant fields correctly.
    • #398: strum is now on rust 2021
    • #391: EnumProperties correctly implements get_bool and get_int finally. 🎉
    • #380: FromString now supports 2 additional attributes, parse_error_ty and parse_error_fn that can be added to use a custom error type rather than the default strum error message.
      • #410: These attributes accept a Path rather than a String to improve behavior with rust-analyzer.

    Breaking Changes

    • #384: MSRV is now 1.66.1
    • #391: EnumProperties doesn't provide default implementations anymore. This would have required you to manually implement this trait which should be very uncommon.
    Open source →
  5. 0.26.3 23 Jun 2024
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.26.2...v0.26.3

    Open source →
    Release notes
    • #344: Hide EnumTable because it's going to be deprecated in the next version.
    • #357: Fixes an incompatiblity with itertools by using the fully qualified name rather than the inherent method.
    • #345: Allows unnamed tuple like variants to use their variants in string interpolation. #[strum(to_string = "Field 0: {0}, Field 1: {1})")] will now work for tuple variants
    Open source →
  6. 0.26.2 10 Mar 2024
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.26.1...v0.26.2

    Open source →
    Release notes
    • #337: Fix missing generic impls for EnumTryAs
    • #334: Support prefix in AsRefStr. Technically a breaking change, but prefix was just added in 0.26.0 so it's a newer feature and it makes the feature more consisent in general.
    Open source →
  7. 0.26.1 28 Jan 2024
    Release notes

    0.26.1

    • #325: use core instead of std in VariantArray.

    0.26.0

    Breaking Changes

    • The EnumVariantNames macro has been renamed VariantNames. The deprecation warning should steer you in
      the right direction for fixing the warning.
    • The Iterator struct generated by EnumIter now has new bounds on it. This shouldn't break code unless you manually
      added the implementation in your code.
    • Display now supports format strings using named fields in the enum variant. This should be a no-op for most code.
      However, if you were outputting a string like "Hello {field}", this will now be interpretted as a format string.
    • EnumDiscriminant now inherits the repr and discriminant values from your main enum. This makes the discriminant type
      closer to a mirror of the original and that's always the goal.

    New features

    • The VariantArray macro has been added. This macro adds an associated constant VARIANTS to your enum. The constant
      is a &'static [Self] slice so that you can access all the variants of your enum. This only works on enums that only
      have unit variants.

      use strum::VariantArray;
      
      #[derive(Debug, VariantArray)]
      enum Color {
        Red,
        Blue,
        Green,
      }
      
      fn main() {
        println!("{:?}", Color::VARIANTS); // prints: ["Red", "Blue", "Green"]
      }
    • The EnumTable macro has been experimentally added. This macro adds a new type that stores an item for each variant
      of the enum. This is useful for storing a value for each variant of an enum. This is an experimental feature because
      I'm not convinced the current api surface area is correct.

      use strum::EnumTable;
      
      #[derive(Copy, Clone, Debug, EnumTable)]
      enum Color {
        Red,
        Blue,
        Green,
      }
      
      fn main() {
        let mut counts = ColorTable::filled(0);
        for color in &[Color::Red, Color::Red, Color::Green]] {
          counts[color] += 1;
        }
      
        assert_eq!(counts[Color::Red], 2);
        assert_eq!(counts[Color::Blue], 0);
        assert_eq!(counts[Color::Green], 1);
      }
    • Display has 2 new features:

      • the strum(prefix = "some_value") attribute on an enum now allows you to prepend a string onto every
        variant when you serialize it.

      • Custom to_string and serialize attributes now support string interopolation on serialization.

    PR's Merged

    • #322: avoid collisions on std::fmt::Debug
    • #321: avoid conflicts with consecutive underscores.
    • #314: add additional bounds to EnumIterator
    • #311: add FusedIterator bounds to EnumIterator
    • #297: New macro, add VariantArray
    • #296: adds prefix attribute to To/From String macros.
    • #294: use named enum fields in to_string macro.
    • #288: discriminant enums now inherit the repr from the original enum.
    • #279: Add EnumTable macro to generate a mapping between fieldless variants and data.
    Open source →
    Release notes
    • #325: use core instead of std in VariantArray.
    Open source →
  8. 0.26.0 28 Jan 2024
    Release notes

    Breaking Changes

    • The EnumVariantNames macro has been renamed VariantNames. The deprecation warning should steer you in the right direction for fixing the warning.
    • The Iterator struct generated by EnumIter now has new bounds on it. This shouldn't break code unless you manually added the implementation in your code.
    • Display now supports format strings using named fields in the enum variant. This should be a no-op for most code. However, if you were outputting a string like "Hello {field}", this will now be interpretted as a format string.
    • EnumDiscriminant now inherits the repr and discriminant values from your main enum. This makes the discriminant type closer to a mirror of the original and that's always the goal.

    New features

    • The VariantArray macro has been added. This macro adds an associated constant VARIANTS to your enum. The constant is a &'static [Self] slice so that you can access all the variants of your enum. This only works on enums that only have unit variants.

      use strum::VariantArray;
      
      #[derive(Debug, VariantArray)]
      enum Color {
        Red,
        Blue,
        Green,
      }
      
      fn main() {
        println!("{:?}", Color::VARIANTS); // prints: ["Red", "Blue", "Green"]
      }
      
    • The EnumTable macro has been experimentally added. This macro adds a new type that stores an item for each variant of the enum. This is useful for storing a value for each variant of an enum. This is an experimental feature because I'm not convinced the current api surface area is correct.

      use strum::EnumTable;
      
      #[derive(Copy, Clone, Debug, EnumTable)]
      enum Color {
        Red,
        Blue,
        Green,
      }
      
      fn main() {
        let mut counts = ColorTable::filled(0);
        for color in &[Color::Red, Color::Red, Color::Green]] {
          counts[color] += 1;
        }
      
        assert_eq!(counts[Color::Red], 2);
        assert_eq!(counts[Color::Blue], 0);
        assert_eq!(counts[Color::Green], 1);
      }
      
    • Display has 2 new features:

      • the strum(prefix = "some_value") attribute on an enum now allows you to prepend a string onto every variant when you serialize it.

      • Custom to_string and serialize attributes now support string interopolation on serialization.

    PR's Merged

    • #322: avoid collisions on std::fmt::Debug
    • #321: avoid conflicts with consecutive underscores.
    • #314: add additional bounds to EnumIterator
    • #311: add FusedIterator bounds to EnumIterator
    • #297: New macro, add VariantArray
    • #296: adds prefix attribute to To/From String macros.
    • #294: use named enum fields in to_string macro.
    • #288: discriminant enums now inherit the repr from the original enum.
    • #279: Add EnumTable macro to generate a mapping between fieldless variants and data.
    Open source →
  9. 0.25.0 18 Jun 2023
    Release notes

    Breaking Changes

    • #261 Upgrade syn dependency to version 2. This bumps the msrv to 1.56. It's impractical to maintain a package where a core dependency of the ecosystem has a different msrv than this one.

    • 270 Change the to_string behavior when using default. Now, when using default, the display method will return the display version of the value contained in the enum rather than the name of the variant.

      #[derive(strum::Display)]
      enum Color {
        Red,
        Blue,
        Green,
        #[strum(default)]
        Other(String)
      }
      
      fn main() {
        // This used to print "Other", now it prints "Purple"
        assert_eq!(Color::Other("Purple".to_string()).to_string(), "Purple");
      }
      

      If you want the old behavior, you can use the to_string attribute to override this behavior. See the PR for an example.

    • 268 Update the behavior of EnumCount to exclude variants that are disabled. This is a breaking change, but the behavior makes it more consistent with other methods.

    New Features

    • #257 This PR adds the EnumIs macro that automatically implements is_{variant_name} methods for each variant.

      #[derive(EnumIs)]
      enum Color {
          Red,
          Blue,
          Green,
      }
      
      #[test]
      fn simple_test() {
          assert!(Color::Red.is_red());
      }
      
    Open source →
  10. 0.24.1 12 Jun 2022
    Release notes
    • #220. Add support for PHF in EnumString (opt-in runtime performance improvements for large enums as #[strum(use_phf)], requires phf feature and increases MSRV to 1.46)
      • #224 tweaked the algorithm.
    • #217: Automatically implement TryFrom in FromRepr. This is technically a breaking change, but the fix is to just remove the manual implementation of TryFrom so it shouldn't be more than a minor inconvenience.
    Open source →
  11. 0.24.0 21 Feb 2022
    Release notes
    • #212. Fix some clippy lints

    • #209. Use core instead of std in a few places.

    • #206. Add get_documentation() to EnumMessage. This provides the ability to get the doc comment for a variant. Currently, very little formatting is done. That is subject to change. Please do not abuse this feature. Rust docs are meant for developer documentation, not long messages for users. However, this may be useful in some situations so we've added support for it.

    • #202. Add a missing doc comment

    • #201. Upgrade Heck version

    Open source →
  12. 0.23.0 17 Nov 2021
    Release notes
    • #185 Adds the FromRepr derive that adds a from_repr(x: usize) -> Option<Self> method to your enum. This lets you convert integer values to your enum. If you specify a #[repr(..)] attribute on your enum, or use an explicit discriminant, this will be incorporated into the derive.

      • from_repr will be const if you use a recent rust version.
      • This cannot be a trait method currently because only inherent methods support const.
    • #186 Automatically implement TryFrom<str> for enums that implement EnumString. This is only enabled for rustc >= 1.34 which is when `TryFrom was stabilized.

      • This is a small breaking change. If you had manually implemented TryFrom<str> for your enum, this will cause a conflict. You can probably remove your manual implementation.
    • #189 Use core::result::Result instead of std::result::Result. This should be more portable in no-std environments.

    Open source →
  13. 0.22.0 11 Oct 2021
    Release notes
    • #180: Deprecates ToString derive. You should use Display instead.

    • #178: Deprecates AsStaticStr. This has been undocumented for a while. The recommended method is to derive IntoStaticStr instead.

    • #171: Improve no-std support.

    • #170: enable changing the path to strum traits. This is necessary if you re-export strum as a submodule in another crate.

    Open source →
  14. 0.21.0 31 May 2021
    Release notes
    • Replace std:: with core:: to support no-std projects. #145

    • Breaking Changes

      • MSRV is updated to 1.32 because heck does not work in 1.31.1 anymore. Rust 1.32 came out Jan 2019 so hopefully teams have moved to an equal or newer version.
      • #149 Remove the "rename" feature. In Rust 2018, macros should be imported using a qualified path to avoid collisions. strum_macros::EnumString rather than using the "Rename" feature to avoid collisions.
      • #160 enum messages: Make the returned values all 'static
        • It is unlikely this will break anyone, but the new signature for functions generated by EnumMessage is fn get_message(&self) -> Option<&'static str>.
    • Added support for ascii_case_insensitive string comparisons. #157 This feature allows FromString impls to match strings that differ in case from the expected variant.

    Open source →
  15. 0.20.0 21 Nov 2020
    Release notes
    • Refactors to do better error handling. Thanks @jplatte for these changes

    • Adding vis(scope) to EnumDiscriminants. #137

      • This feature works best with versions of rust >= 1.34 due to a rustc parsing error in earlier versions.
      • Earlier versions can still use vis(r#pub)
    • These changes should not be breaking, but the amount of code modified was significant.

    • FYI about #122. The macro renames feature will be removed in early 2021. This feature was only necessary in rust 2015 because macros didn't support qualified imports so macro names could collide between crates.

    Open source →
  16. 0.19.5 07 Oct 2020
    Release notes
    • Updated docs
    Open source →
  17. 0.19.4 07 Oct 2020

    Nothing published for this version

  18. 0.19.3 07 Oct 2020
    Release notes
    • Properly error on malformed strum attributes. #119
      • These types of inputs have historically been ignore silently. This may break code that is already incorrect.
    • Move docs back to rust docs. #121
    • Updated the docs a second time to improve discoverability.
    Open source →
  19. 0.19.2 06 Aug 2020
    Release notes
    Open source →
  20. 0.19.1 02 Aug 2020
    Release notes
    • Breaking Change: EnumVariantNames now properly adjusts to the to_string and serialize attributes.
    • There's a regression in this release that may make strum imcompatible with other plugins if those plugins use non-rust syntax in their attributes. #104
    Open source →
  21. 0.19.0 01 Aug 2020
    Release notes
    • Fixed a regression using nth_back. #85

    • Added repository to Cargo.toml. #90

    • Correctly handle fill align in Display impls. #95

    • Breaking Change: Use Associated Constant for EnumCount instead of const fn and free constant. #99 This behavior is consistent with the other derives.

    • Breaking Change. default and disabled should now be written as markers instead of key value pairs. Here is the old way of adding these attributes to a variant.

      // OLD WAY
      enum Test {
        #[strum(disabled = "true", default = "true")]
        Variant(String)
      }
      

      Here is the new way. There is less ambiguity in the new syntax.

      enum Test {
        #[strum(disabled, default)]
        Variant(String)
      }
      
    • Breaking Change. Most of the strum plugins will now error more aggresively on invalid options being used. Historically, the plugins have ignore invalid options, but most of these should error now. Silent errors are a rust anti-pattern.

    Open source →
  22. 0.18.0 02 Mar 2020
    Release notes
    • Only copy across "doc", "cfg", "allow", "deny" attributes from main enum variants to discriminant variants. #73
    • The formatting of generated serialization variants returned by get_serializations() from an enum that derives EnumMessage is now affected by the serialize_all property on the enum. #84
    • IntoEnumIterator now has the constraint IntoEnumIterator::Iterator<Item=Self> and Self: Sized. This makes it much easier to be generic over IntoEnumIterator and enum variants must be sized. [#80]
    Open source →
  23. 0.17.1 20 Dec 2019
    Release notes
    • Fixed an issue caused by combining #60 and #76
    Open source →
  24. 0.17.0 19 Dec 2019 withdrawn
    Release notes
    • Breaking Change. Enum variant names now exports an associated constant VARIANTS in the strum::VariantNames trait instead of adding a variants method directly to the enum. The fix is to use strum::VariantNames in your module and replace occurrances of variants() with VARIANTS.
    • 🐛 fix - stop incrementing iterator index after we reach the end. #76
    • Strum iterators now implemented DoubleEndedIterator. #60
    Open source →
  25. 0.16.0 18 Sep 2019
    Release notes
    • Added serialize UPPERCASE
    • Added "case-styles" to match the formatting convention they imply such as kebab-case and camelCase.
    • Added Enum Variant Names to improve compatibility with structopt and clap. #56
    • Added derive re-export to strum to allow re-exporting macros from main crate. #57
    • Bumped syn and quote to 1.0. This raises minimal compatible rust version to 1.31.
    • Did internal refactoring to improve organization of code. Shouldn't change user-facing api though.
    • Added license file to subdirectories so they are included in crate distros.
    Open source →
  26. 0.15.0 27 Mar 2019
    Release notes

    Added

    • Added Feature flags to rename macros. This is to improve compatibility with older versions of rust. Wiki
    Open source →
  27. 0.14.0 04 Mar 2019
    Release notes

    Added

    • Allow Missing Docs on EnumCount. PR #43
    • Fix serialize_all in AsRefStr, AsStaticStr and IntoStaticStr. PR #42
      • This is a bug fix, but it may break code that was relying on the incorrect behavior.
    Open source →
  28. 0.13.0 24 Dec 2018
    Release notes

    Added

    • Added a derive to implement From<YourEnum> for &'static str. This deprecates AsStaticStr since the new solution doesn't require a strum specific trait to use.
    Open source →
  29. 0.12.0 05 Dec 2018
    Release notes

    Added

    • Serialization case can be controlled using #[strum(serialize_all = "snake_case")]. (#21)
    • #[derive(EnumDiscriminants)] generates enum with variants without fields. (#33)
    Open source →
  30. 0.11.0 26 Sep 2018

    Nothing published for this version

  31. 0.10.0 23 Jun 2018
    Release notes

    Added

    • Implemented Clone for EnumIters. (#18)
    • Added AsStaticRef derive to allow enums to impl AsStaticRef<str>. (#23)

    Fixed

    • #[allow(missing_docs)] on generated EnumIters. (#19)
    Open source →
  32. 0.9.0 10 Mar 2018

    Nothing published for this version

  33. 0.8.0 24 Aug 2017

    Nothing published for this version

  34. 0.6.0 16 Apr 2017

    Nothing published for this version

  35. 0.5.1 25 Feb 2017

    Nothing published for this version

  36. 0.5.0 23 Feb 2017

    Nothing published for this version

  37. 0.2.2 16 Feb 2017

    Nothing published for this version

  38. 0.2.1 16 Feb 2017

    Nothing published for this version

  39. 0.2.0 16 Feb 2017

    Nothing published for this version

  40. 0.1.0 12 Feb 2017

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive