strum-0.25.0/Cargo.toml0000644000000025070000000000100102740ustar # 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 are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "strum" version = "0.25.0" authors = ["Peter Glotfelty "] description = "Helpful macros for working with enums and strings" homepage = "https://github.com/Peternator7/strum" documentation = "https://docs.rs/strum" readme = "../README.md" keywords = ["enum", "string", "macros", "proc-macros"] categories = ["development-tools::procedural-macro-helpers", "parsing"] license = "MIT" repository = "https://github.com/Peternator7/strum" [package.metadata.docs.rs] features = ["derive"] rustdoc-args = ["--cfg", "docsrs"] [dependencies.phf] version = "0.10" features = ["macros"] optional = true [dependencies.strum_macros] version = "0.25" optional = true [dev-dependencies.strum_macros] version = "0.25" [features] default = ["std"] derive = ["strum_macros"] std = [] [badges.travis-ci] repository = "Peternator7/strum" strum-0.25.0/Cargo.toml.orig000064400000000000000000000016710072674642500140060ustar 00000000000000[package] name = "strum" version = "0.25.0" edition = "2018" authors = ["Peter Glotfelty "] license = "MIT" description = "Helpful macros for working with enums and strings" keywords = ["enum", "string", "macros", "proc-macros"] categories = ["development-tools::procedural-macro-helpers", "parsing"] documentation = "https://docs.rs/strum" homepage = "https://github.com/Peternator7/strum" repository = "https://github.com/Peternator7/strum" readme = "../README.md" [dependencies] strum_macros = { path = "../strum_macros", optional = true, version = "0.25" } phf = { version = "0.10", features = ["macros"], optional = true } [dev-dependencies] strum_macros = { path = "../strum_macros", version = "0.25" } [badges] travis-ci = { repository = "Peternator7/strum" } [features] default = ["std"] derive = ["strum_macros"] std = [] [package.metadata.docs.rs] features = ["derive"] rustdoc-args = ["--cfg", "docsrs"] strum-0.25.0/LICENSE000064400000000000000000000020600072674642500121150ustar 00000000000000MIT License Copyright (c) 2019 Peter Glotfelty Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. strum-0.25.0/src/additional_attributes.rs000064400000000000000000000074140072674642500166330ustar 00000000000000//! # Documentation for Additional Attributes //! //! ## Attributes on Enums //! //! Strum supports several custom attributes to modify the generated code. At the enum level, the following attributes are supported: //! //! - `#[strum(serialize_all = "case_style")]` attribute can be used to change the case used when serializing to and deserializing //! from strings. This feature is enabled by [withoutboats/heck](https://github.com/withoutboats/heck) and supported case styles are: //! //! - `camelCase` //! - `PascalCase` //! - `kebab-case` //! - `snake_case` //! - `SCREAMING_SNAKE_CASE` //! - `SCREAMING-KEBAB-CASE` //! - `lowercase` //! - `UPPERCASE` //! - `title_case` //! - `mixed_case` //! - `Train-Case` //! //! ```rust //! use strum_macros; //! //! #[derive(Debug, Eq, PartialEq, strum_macros::Display)] //! #[strum(serialize_all = "snake_case")] //! enum Brightness { //! DarkBlack, //! Dim { //! glow: usize, //! }, //! #[strum(serialize = "bright")] //! BrightWhite, //! } //! //! assert_eq!( //! String::from("dark_black"), //! Brightness::DarkBlack.to_string().as_ref() //! ); //! assert_eq!( //! String::from("dim"), //! Brightness::Dim { glow: 0 }.to_string().as_ref() //! ); //! assert_eq!( //! String::from("bright"), //! Brightness::BrightWhite.to_string().as_ref() //! ); //! ``` //! //! - You can also apply the `#[strum(ascii_case_insensitive)]` attribute to the enum, //! and this has the same effect of applying it to every variant. //! //! ## Attributes on Variants //! //! Custom attributes are applied to a variant by adding `#[strum(parameter="value")]` to the variant. //! //! - `serialize="..."`: Changes the text that `FromStr()` looks for when parsing a string. This attribute can //! be applied multiple times to an element and the enum variant will be parsed if any of them match. //! //! - `to_string="..."`: Similar to `serialize`. This value will be included when using `FromStr()`. More importantly, //! this specifies what text to use when calling `variant.to_string()` with the `Display` derivation, or when calling `variant.as_ref()` with `AsRefStr`. //! //! - `default`: Applied to a single variant of an enum. The variant must be a Tuple-like //! variant with a single piece of data that can be create from a `&str` i.e. `T: From<&str>`. //! The generated code will now return the variant with the input string captured as shown below //! instead of failing. //! //! ```text //! // Replaces this: //! _ => Err(strum::ParseError::VariantNotFound) //! // With this in generated code: //! default => Ok(Variant(default.into())) //! ``` //! The plugin will fail if the data doesn't implement From<&str>. You can only have one `default` //! on your enum. //! //! - `disabled`: removes variant from generated code. //! //! - `ascii_case_insensitive`: makes the comparison to this variant case insensitive (ASCII only). //! If the whole enum is marked `ascii_case_insensitive`, you can specify `ascii_case_insensitive = false` //! to disable case insensitivity on this v ariant. //! //! - `message=".."`: Adds a message to enum variant. This is used in conjunction with the `EnumMessage` //! trait to associate a message with a variant. If `detailed_message` is not provided, //! then `message` will also be returned when `get_detailed_message` is called. //! //! - `detailed_message=".."`: Adds a more detailed message to a variant. If this value is omitted, then //! `message` will be used in it's place. //! //! - Structured documentation, as in `/// ...`: If using `EnumMessage`, is accessible via get_documentation(). //! //! - `props(key="value")`: Enables associating additional information with a given variant. strum-0.25.0/src/lib.rs000064400000000000000000000160310072674642500130160ustar 00000000000000//! # Strum //! //! [![Build Status](https://travis-ci.org/Peternator7/strum.svg?branch=master)](https://travis-ci.org/Peternator7/strum) //! [![Latest Version](https://img.shields.io/crates/v/strum.svg)](https://crates.io/crates/strum) //! [![Rust Documentation](https://docs.rs/strum/badge.svg)](https://docs.rs/strum) //! //! Strum is a set of macros and traits for working with //! enums and strings easier in Rust. //! //! The full version of the README can be found on [GitHub](https://github.com/Peternator7/strum). //! //! # 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. //! //! ```toml //! [dependencies] //! strum = "0.25" //! strum_macros = "0.25" //! //! # You can also access strum_macros exports directly through strum using the "derive" feature //! strum = { version = "0.25", features = ["derive"] } //! ``` //! #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(docsrs, feature(doc_cfg))] // only for documentation purposes pub mod additional_attributes; #[cfg(feature = "phf")] #[doc(hidden)] pub use phf as _private_phf_reexport_for_macro_if_phf_feature; /// The `ParseError` enum is a collection of all the possible reasons /// an enum can fail to parse from a string. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub enum ParseError { VariantNotFound, } #[cfg(feature = "std")] impl std::fmt::Display for ParseError { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { // We could use our macro here, but this way we don't take a dependency on the // macros crate. match self { ParseError::VariantNotFound => write!(f, "Matching variant not found"), } } } #[cfg(feature = "std")] impl std::error::Error for ParseError { fn description(&self) -> &str { match self { ParseError::VariantNotFound => { "Unable to find a variant of the given enum matching the string given. Matching \ can be extended with the Serialize attribute and is case sensitive." } } } } /// This trait designates that an `Enum` can be iterated over. It can /// be auto generated using `strum_macros` on your behalf. /// /// # Example /// /// ```rust /// # use std::fmt::Debug; /// // You need to bring the type into scope to use it!!! /// use strum::{EnumIter, IntoEnumIterator}; /// /// #[derive(EnumIter, Debug)] /// enum Color { /// Red, /// Green { range: usize }, /// Blue(usize), /// Yellow, /// } /// /// // Iterate over the items in an enum and perform some function on them. /// fn generic_iterator(pred: F) /// where /// E: IntoEnumIterator, /// F: Fn(E), /// { /// for e in E::iter() { /// pred(e) /// } /// } /// /// generic_iterator::(|color| println!("{:?}", color)); /// ``` pub trait IntoEnumIterator: Sized { type Iterator: Iterator; fn iter() -> Self::Iterator; } pub trait VariantIterator: Sized { type Iterator: Iterator; fn iter() -> Self::Iterator; } pub trait VariantMetadata { const VARIANT_COUNT: usize; const VARIANT_NAMES: &'static [&'static str]; fn variant_name(&self) -> &'static str; } /// Associates additional pieces of information with an Enum. This can be /// autoimplemented by deriving `EnumMessage` and annotating your variants with /// `#[strum(message="...")]`. /// /// # Example /// /// ```rust /// # use std::fmt::Debug; /// // You need to bring the type into scope to use it!!! /// use strum::EnumMessage; /// /// #[derive(PartialEq, Eq, Debug, EnumMessage)] /// enum Pet { /// #[strum(message="I have a dog")] /// #[strum(detailed_message="My dog's name is Spots")] /// Dog, /// /// I am documented. /// #[strum(message="I don't have a cat")] /// Cat, /// } /// /// let my_pet = Pet::Dog; /// assert_eq!("I have a dog", my_pet.get_message().unwrap()); /// ``` pub trait EnumMessage { fn get_message(&self) -> Option<&'static str>; fn get_detailed_message(&self) -> Option<&'static str>; /// Get the doc comment associated with a variant if it exists. fn get_documentation(&self) -> Option<&'static str>; fn get_serializations(&self) -> &'static [&'static str]; } /// `EnumProperty` is a trait that makes it possible to store additional information /// with enum variants. This trait is designed to be used with the macro of the same /// name in the `strum_macros` crate. Currently, the only string literals are supported /// in attributes, the other methods will be implemented as additional attribute types /// become stabilized. /// /// # Example /// /// ```rust /// # use std::fmt::Debug; /// // You need to bring the type into scope to use it!!! /// use strum::EnumProperty; /// /// #[derive(PartialEq, Eq, Debug, EnumProperty)] /// enum Class { /// #[strum(props(Teacher="Ms.Frizzle", Room="201"))] /// History, /// #[strum(props(Teacher="Mr.Smith"))] /// #[strum(props(Room="103"))] /// Mathematics, /// #[strum(props(Time="2:30"))] /// Science, /// } /// /// let history = Class::History; /// assert_eq!("Ms.Frizzle", history.get_str("Teacher").unwrap()); /// ``` pub trait EnumProperty { fn get_str(&self, prop: &str) -> Option<&'static str>; fn get_int(&self, _prop: &str) -> Option { Option::None } fn get_bool(&self, _prop: &str) -> Option { Option::None } } /// A cheap reference-to-reference conversion. Used to convert a value to a /// reference value with `'static` lifetime within generic code. #[deprecated( since = "0.22.0", note = "please use `#[derive(IntoStaticStr)]` instead" )] pub trait AsStaticRef where T: ?Sized, { fn as_static(&self) -> &'static T; } /// A trait for capturing the number of variants in Enum. This trait can be autoderived by /// `strum_macros`. pub trait EnumCount { const COUNT: usize; } /// A trait for retrieving the names of each variant in Enum. This trait can /// be autoderived by `strum_macros`. pub trait VariantNames { /// Names of the variants of this enum const VARIANTS: &'static [&'static str]; } #[cfg(feature = "derive")] pub use strum_macros::*; macro_rules! DocumentMacroRexports { ($($export:ident),+) => { $( #[cfg(all(docsrs, feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] pub use strum_macros::$export; )+ }; } // We actually only re-export these items individually if we're building // for docsrs. You can do a weird thing where you rename the macro // and then reference it through strum. The renaming feature should be deprecated now that // 2018 edition is almost 2 years old, but we'll need to give people some time to do that. DocumentMacroRexports! { AsRefStr, AsStaticStr, Display, EnumCount, EnumDiscriminants, EnumIter, EnumMessage, EnumProperty, EnumString, EnumVariantNames, FromRepr, IntoStaticStr, ToString }