NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #163 most downloaded on crates.io
Helpful macros for working with enums and strings
Last release 7 months ago
22 Feb 2026
Release timing varies
gaps range from 8 days to 10 months
Most releases are documented
notes for 34 of 47 stable releases
2 versions withdrawn
withdrawn after publishing
10 years old
49 releases · first in 2017
Updated the CHANGELOG for the new release by @Peternator7 in #452
#[automatically_derived] by @clechasseur in #462phf to v0.13 by @paolobarbolini in #465EnumDiscriminants by @clechasseur in #461Full Changelog: v0.27.2...v0.28.0
One column per quarter.
#461: Allow any kind of passthrough attributes on EnumDiscriminants.
#[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 },
}
Adding support for doc comments on EnumDiscriminants generated type… by @linclelinkpart5 in #141
EnumDiscriminants generated type… by @linclelinkpart5 in #141rustversion dependency by @paolobarbolini in #446phf to v0.12 by @paolobarbolini in #448#[automatically_derived] to the impls by @dandedotdev in #444suffix attribute for serialization of enum variants by @amogh-dambal in #440Full Changelog: v0.27.1...v0.27.2
#141: Adding support for doc comments on EnumDiscriminants generated type.
#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
#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.
Fix docsrs build error regarding IntoDiscriminant trait by @tveness in #414
#[strum(transparent)] attribute by @bobozaur in #331Full Changelog: v0.27.0...v0.27.1
#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
}
Fix the unconditional usage of string interpolation in strum by @Peternator7 in #360
enum_iter docs by @cenviity in #387const_into_str attribute to enable static string conversions in const contexts by @biryukovmaxim in #353get_int/get_bool for properties by @marxin in #391Display macro in #![no_std] programs by @bugadani in #407Full Changelog: v0.26.3...v0.27.0
Display is now correctly derived in [no_std] projects.EnumIter now implements Send + SyncEnumTryAs now handles attributes on variant fields correctly.strum is now on rust 2021EnumProperties correctly implements get_bool and get_int
finally. 🎉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.
Path rather than a String
to improve behavior with rust-analyzer.* #360: Fixes bug introduced with new string interpolation feature where unit structs took an implicit unnecessary dependency on ::alloc.
::core::alloc.Fix typos & misspellings in docs by @5-pebbles in #347
heck requirement by @smoelius in #346get on an EnumIter, eliminating ambiguities by @bluurryy in #357Full Changelog: v0.26.2...v0.26.3
EnumTable because it's going to be deprecated in the next
version.itertools by using the fully
qualified name rather than the inherent method.#[strum(to_string = "Field 0: {0}, Field 1: {1})")] will now work for tuple variantsEnumTable will likely be deprecated.
prefix attribute for AsRefStr derive by @vbrvk in #334Full Changelog: v0.26.1...v0.26.2
The EnumVariantNames macro has been renamed VariantNames . The deprecation warning should steer you in the right direction for fixing the warning.
core instead of std in VariantArray.EnumVariantNames macro has been renamed VariantNames. The deprecation warning should steer you inDisplay now supports format strings using named fields in the enum variant. This should be a no-op for most code."Hello {field}", this will now be interpretted as a format string.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.
std::fmt::DebugVariantArrayEnumTable macro to generate a mapping between fieldless variants and data.The EnumVariantNames macro has been renamed VariantNames. The deprecation warning should steer you in the right direction for fixing the warning.
EnumVariantNames macro has been renamed VariantNames. The deprecation warning should steer you in
the right direction for fixing the warning.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.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.
std::fmt::DebugVariantArrayEnumTable macro to generate a mapping between fieldless variants and data.Received a number of bug fix PR's.
* #289: Enables a previously disabled rustdoc. * #287: Fixes a bug in EnumIter code gen so that we produce ::core to avoid issues with shadowing modul
* #276. Fixes #275 and #281. Not sure exactly why this broke, perhaps incompatibilities between syn 1 and 2. PR fixes the issue by only looking at att
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…
#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.
#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());
}
* #231 Add ignore lints for EnumIter not implementing Copy or Debug on the generated iter struct. Copy should generally not be implemented on Iterator
Reverted #217 because it was disruptive and non-trivial to work around if you hit it.
* #220. Add support for PHF in EnumString (opt-in runtime performance improvements for large enums as #[strum(use_phf)], requires phf feature and incr
EnumString (opt-in runtime
performance improvements for large enums as #[strum(use_phf)], requires phf feature and increases MSRV to 1.46)
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.* #212. Fix some clippy lints * #209. Use core instead of std in a few places. * #206. Add get_documentation() to EnumMessage. This provides the abili
#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
* #193 Fixes an ambiguity introduced by #186 when your enum has a variant called Error. * #192 The work done in #189 was lost in other PR's. This re-a
This is a small breaking change. If you had manually implemented TryFrom for your enum, this will cause a conflict. You can probably remove your manua…
#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.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.
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.
* #180: Deprecates ToString derive. You should use Display instead. * #178: Deprecates AsStaticStr. This has been undocumented for a while. The recomm
#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.
* #164 Improve compatibility with older versions of syn.
syn.Replace std:: with core:: to support no-std projects. #145
Replace std:: with core:: to support no-std projects. #145
Breaking Changes
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.strum_macros::EnumString rather than using the "Rename"
feature to avoid collisions.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.
Nothing published for this version
Refactors to do better error handling. Thanks @jplatte for these changes
Refactors to do better error handling. Thanks @jplatte for these changes
Adding vis(scope) to EnumDiscriminants. #137
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.
Nothing published for this version
Properly error on malformed strum attributes. #119
* Fixes #104. PR #105
Breaking Change: EnumVariantNames now properly adjusts to the to_string and serialize attributes.
to_string and serialize attributes.Breaking Change: Use Associated Constant for EnumCount instead of const fn and free constant. #99 This behavior is consistent with the other derives.
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.
Only copy across "doc", "cfg", "allow", "deny" attributes from main enum variants to discriminant variants. #73
"doc", "cfg", "allow", "deny" attributes from main enum variants to discriminant variants. #73get_serializations() from an
enum that derives EnumMessage is now affected by the serialize_all property on the enum.
#84IntoEnumIterator::Iterator<Item=Self> and Self: Sized. This makes
it much easier to be generic over IntoEnumIterator and enum variants must be sized. [#80]Fixed an issue caused by combining #60 and #76
Breaking Change. Enum variant names now exports an associated constant VARIANTS in the strum::VariantNames trait instead of adding a variants method d…
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.
Added "case-styles" to match the formatting convention they imply such as kebab-case and camelCase.
kebab-case and camelCase.structopt and clap. #56strum to allow re-exporting macros from main crate. #571.0. This raises minimal compatible rust version to 1.31.Added Feature flags to rename macros. This is to improve compatibility with older versions of rust. Wiki
Allow Missing Docs on EnumCount. PR #43
Added a derive to implement From for &'static str. This deprecates AsStaticStr since the new solution doesn't require a strum specific trait to use.
From<YourEnum> for &'static str. This deprecates AsStaticStr since
the new solution doesn't require a strum specific trait to use.Serialization case can be controlled using #[strum(serialize_all = "snake_case")]. ([#21][#21])
Nothing published for this version
Implemented Clone for EnumIters. ([#18][#18])
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →