1
0
mirror of https://github.com/danog/strum.git synced 2024-11-30 04:28:59 +01:00

Did a little bit of refactoring and added some docs around AsStaticStr (#28)

* Did a little bit of refactoring and added some docs around AsStaticStr

* Revving the version in the cargoo.toml

* Managing Cargo.toml is a bit tedious when deploying packages that depend on each other

* Updated Cargo.toml
This commit is contained in:
Peter Glotfelty 2018-06-26 08:22:19 -07:00 committed by GitHub
parent c91854c2f1
commit b6e4e66157
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 133 additions and 30 deletions

View File

@ -14,8 +14,8 @@ Cargo.toml. Strum_macros contains the macros needed to derive all the traits in
```toml
[dependencies]
strum = "0.9.0"
strum_macros = "0.9.0"
strum = "0.10.0"
strum_macros = "0.10.0"
```
And add these lines to the root of your project, either lib.rs or main.rs.
@ -135,6 +135,35 @@ Strum has implemented the following macros:
`ToString` for determining what string is returned. The difference is that `as_ref()` returns
a `&str` instead of a `String` so you don't allocate any additional memory with each call.
4. `AsStaticStr`: this is similar to `AsRefStr`, but returns a `'static` reference to a string which is helpful
in some scenarios. This macro implements `strum::AsStaticRef<str>` which adds a method `.to_static()` that
returns a `&'static str`.
```rust
extern crate strum;
#[macro_use] extern crate strum_macros;
use strum::AsStaticRef;
#[derive(AsStaticStr)]
enum State<'a> {
Initial(&'a str),
Finished
}
fn print_state<'a>(s:&'a str) {
let state = State::Initial(s);
// The following won't work because the lifetime is incorrect so we can use.as_static() instead.
// let wrong: &'static str = state.as_ref();
let right: &'static str = state.as_static();
println!("{}", right);
}
fn main() {
print_state(&"hello world".to_string())
}
```
4. `EnumIter`: iterate over the variants of an Enum. Any additional data on your variants will be
set to `Default::default()`. The macro implements `strum::IntoEnumIter` on your enum and
creates a new type called `YourEnumIter` that is the iterator object. You cannot derive

View File

@ -1,6 +1,6 @@
[package]
name = "strum"
version = "0.9.0"
version = "0.10.0"
authors = ["Peter Glotfelty <peglotfe@microsoft.com>"]
license = "MIT"
@ -13,9 +13,8 @@ homepage = "https://github.com/Peternator7/strum"
readme = "../README.md"
[dev-dependencies]
strum_macros = "0.9.0"
strum_macros = "0.10.0"
# strum_macros = { path = "../strum_macros" }
[badges]
travis-ci = { repository = "Peternator7/strum" }

View File

@ -121,8 +121,36 @@
//!
//! 3. `AsRefStr`: this derive implements `AsRef<str>` on your enum using the same rules as
//! `ToString` for determining what string is returned. The difference is that `as_ref()` returns
//! a `&str` instead of a `String` so you don't allocate any additional memory with each call.
//! a borrowed `str` instead of a `String` so you can save an allocation.
//!
//! 4. `AsStaticStr`: this is similar to `AsRefStr`, but returns a `'static` reference to a string which is helpful
//! in some scenarios. This macro implements `strum::AsStaticRef<str>` which adds a method `.as_static()` that
//! returns a `&'static str`.
//!
//! ```rust
//! # extern crate strum;
//! # #[macro_use] extern crate strum_macros;
//! use strum::AsStaticRef;
//!
//! #[derive(AsStaticStr)]
//! enum State<'a> {
//! Initial(&'a str),
//! Finished
//! }
//!
//! fn print_state<'a>(s:&'a str) {
//! let state = State::Initial(s);
//! // The following won't work because the lifetime is incorrect so we can use.as_static() instead.
//! // let wrong: &'static str = state.as_ref();
//! let right: &'static str = state.as_static();
//! println!("{}", right);
//! }
//!
//! fn main() {
//! print_state(&"hello world".to_string())
//! }
//! ```
//!
//! 4. `EnumIter`: iterate over the variants of an Enum. Any additional data on your variants will be
//! set to `Default::default()`. The macro implements `strum::IntoEnumIter` on your enum and
//! creates a new type called `YourEnumIter` that implements both `Iterator` and `ExactSizeIterator`.

View File

@ -1,6 +1,6 @@
[package]
name = "strum_macros"
version = "0.9.0"
version = "0.10.0"
authors = ["Peter Glotfelty <peglotfe@microsoft.com>"]
license = "MIT"

View File

@ -3,15 +3,14 @@ use syn;
use helpers::{unique_attr, extract_attrs, extract_meta, is_disabled};
pub fn as_ref_str_inner(ast: &syn::DeriveInput) -> TokenStream {
fn get_arms(ast: &syn::DeriveInput) -> Vec<TokenStream> {
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let mut arms = Vec::new();
let variants = match ast.data {
syn::Data::Enum(ref v) => &v.variants,
_ => panic!("AsRefStr only works on Enums"),
_ => panic!("This macro only works on Enums"),
};
let mut arms = Vec::new();
for variant in variants {
use syn::Fields::*;
let ident = &variant.ident;
@ -53,14 +52,29 @@ pub fn as_ref_str_inner(ast: &syn::DeriveInput) -> TokenStream {
})
}
let arms = &arms;
arms
}
pub fn as_ref_str_inner(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let arms = get_arms(ast);
quote!{
impl #impl_generics ::std::convert::AsRef<str> for #name #ty_generics #where_clause {
fn as_ref(&self) -> &str {
::strum::AsStaticRef::as_static(self)
match *self {
#(#arms),*
}
}
}
}
}
pub fn as_static_str_inner(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let arms = get_arms(ast);
quote!{
impl #impl_generics ::strum::AsStaticRef<str> for #name #ty_generics #where_clause {
fn as_static(&self) -> &'static str {
match *self {

View File

@ -58,6 +58,15 @@ pub fn as_ref_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
toks.into()
}
#[proc_macro_derive(AsStaticStr,attributes(strum))]
pub fn as_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse(input).unwrap();
let toks = as_ref_str::as_static_str_inner(&ast);
debug_print_generated(&ast, &toks);
toks.into()
}
#[proc_macro_derive(ToString,attributes(strum))]
pub fn to_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse(input).unwrap();

View File

@ -1,6 +1,6 @@
[package]
name = "strum_tests"
version = "0.9.0"
version = "0.9.1"
authors = ["Peter Glotfelty <peglotfe@microsoft.com>"]
[dependencies]

View File

@ -0,0 +1,34 @@
#[macro_use]
extern crate strum_macros;
#[derive(Debug,Eq,PartialEq,AsRefStr)]
enum Color {
#[strum(to_string="RedRed")]
Red,
#[strum(serialize="b", to_string="blue")]
Blue { hue: usize },
#[strum(serialize="y", serialize="yellow")]
Yellow,
#[strum(default="true")]
Green(String),
}
#[test]
fn as_red_str() {
assert_eq!("RedRed", (Color::Red).as_ref());
}
#[test]
fn as_blue_str() {
assert_eq!("blue", (Color::Blue { hue: 0 }).as_ref());
}
#[test]
fn as_yellow_str() {
assert_eq!("yellow", (Color::Yellow).as_ref());
}
#[test]
fn as_green_str() {
assert_eq!("Green", (Color::Green(String::default())).as_ref());
}

View File

@ -3,10 +3,9 @@ extern crate strum;
extern crate strum_macros;
use std::str::FromStr;
use strum::AsStaticRef;
#[derive(Debug,Eq,PartialEq,EnumString,AsRefStr)]
#[derive(Debug,Eq,PartialEq,EnumString,AsRefStr,AsStaticStr)]
enum Color {
#[strum(to_string="RedRed")]
Red,
@ -18,35 +17,26 @@ enum Color {
Green(String),
}
#[test]
fn color_simple() {
assert_eq!(Color::Red, Color::from_str("RedRed").unwrap());
}
#[test]
fn as_red_str() {
assert_eq!("RedRed",
(Color::Red).as_ref());
assert_eq!(Color::Red,
Color::from_str((Color::Red).as_ref()).unwrap());
let _: &'static str = Color::Red.as_static();
assert_eq!("RedRed", (Color::Red).as_ref());
assert_eq!(Color::Red, Color::from_str((Color::Red).as_ref()).unwrap());
}
#[test]
fn as_blue_str() {
assert_eq!("blue",
(Color::Blue { hue: 0 }).as_ref());
assert_eq!("blue", (Color::Blue { hue: 0 }).as_ref());
let _: &'static str = (Color::Blue { hue: 0 }).as_static();
}
#[test]
fn as_yellow_str() {
assert_eq!("yellow", (Color::Yellow).as_ref());
let _: &'static str = Color::Yellow.as_static();
let _: &'static str = (Color::Yellow).as_static();
}
#[test]
fn as_green_str() {
assert_eq!("Green", (Color::Green(String::default())).as_ref());
let _: &'static str = Color::Green(String::default()).as_static();
let _: &'static str = (Color::Green(String::default())).as_static();
}