File tree Expand file tree Collapse file tree 8 files changed +100
-8
lines changed
Expand file tree Collapse file tree 8 files changed +100
-8
lines changed Original file line number Diff line number Diff line change @@ -26,16 +26,17 @@ extern crate bitflags;
2626extern crate bitflags_derive;
2727
2828bitflags! {
29- #[derive(FlagsDebug )]
30- struct Flags : u8 {
29+ #[derive(FlagsDisplay , FlagsFromStr )]
30+ struct MyFlags : u8 {
3131 const A = 1 ;
3232 const B = 1 << 1 ;
3333 const C = 1 << 2 ;
3434 }
3535}
3636
37- // The regular `#[derive(Debug)]` would produce "Flags(A | B)" here
38- assert_eq! (" A | B" , format! (" {:?}" , Flags :: A | Flags :: B ));
37+ let flags = " A | B" . parse :: <MyFlags >()? ;
38+
39+ assert_eq! (" A | B" , flags . to_string ());
3940```
4041
4142See [ the docs] ( https://docs.rs/bitflags-derive ) for details on all supported attributes.
Original file line number Diff line number Diff line change 1+ use proc_macro2:: TokenStream ;
2+
3+ pub ( crate ) fn expand ( item : syn:: DeriveInput ) -> Result < TokenStream , syn:: Error > {
4+ let ident = item. ident ;
5+ let ( impl_generics, ty_generics, where_clause) = item. generics . split_for_impl ( ) ;
6+
7+ Ok (
8+ quote ! ( impl #impl_generics bitflags_derive:: __private:: core:: fmt:: Display for #ident #ty_generics #where_clause {
9+ fn fmt( & self , f: & mut bitflags_derive:: __private:: core:: fmt:: Formatter ) -> bitflags_derive:: __private:: core:: fmt:: Result {
10+ bitflags_derive:: __private:: bitflags:: parser:: to_writer( self , f)
11+ }
12+ } ) ,
13+ )
14+ }
Original file line number Diff line number Diff line change 1+ use proc_macro2:: TokenStream ;
2+
3+ pub ( crate ) fn expand ( item : syn:: DeriveInput ) -> Result < TokenStream , syn:: Error > {
4+ let ident = item. ident ;
5+ let ( impl_generics, ty_generics, where_clause) = item. generics . split_for_impl ( ) ;
6+
7+ Ok (
8+ quote ! ( impl #impl_generics bitflags_derive:: __private:: core:: str :: FromStr for #ident #ty_generics #where_clause {
9+ type Err = bitflags_derive:: __private:: bitflags:: parser:: ParseError ;
10+
11+ fn from_str( v: & str ) -> bitflags_derive:: __private:: core:: result:: Result <Self , bitflags_derive:: __private:: bitflags:: parser:: ParseError > {
12+ bitflags_derive:: __private:: bitflags:: parser:: from_str( v)
13+ }
14+ } ) ,
15+ )
16+ }
Original file line number Diff line number Diff line change @@ -12,9 +12,11 @@ extern crate proc_macro;
1212extern crate quote;
1313
1414mod debug;
15+ mod display;
16+ mod from_str;
1517
1618/**
17- Derive [`Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html) for a flags type .
19+ Derive [`Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html).
1820
1921This macro will use [`to_writer`](https://docs.rs/bitflags/latest/bitflags/parser/fn.to_writer.html) to
2022format flags values.
@@ -24,6 +26,28 @@ pub fn derive_bitflags_debug(item: proc_macro::TokenStream) -> proc_macro::Token
2426 debug:: expand ( syn:: parse_macro_input!( item as syn:: DeriveInput ) ) . unwrap_or_compile_error ( )
2527}
2628
29+ /**
30+ Derive [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html).
31+
32+ This macro will use [`to_writer`](https://docs.rs/bitflags/latest/bitflags/parser/fn.to_writer.html) to
33+ format flags values.
34+ */
35+ #[ proc_macro_derive( FlagsDisplay ) ]
36+ pub fn derive_bitflags_display ( item : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
37+ display:: expand ( syn:: parse_macro_input!( item as syn:: DeriveInput ) ) . unwrap_or_compile_error ( )
38+ }
39+
40+ /**
41+ Derive [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html).
42+
43+ This macro will use [`from_str`](https://docs.rs/bitflags/latest/bitflags/parser/fn.from_str.html) to
44+ parse flags values.
45+ */
46+ #[ proc_macro_derive( FlagsFromStr ) ]
47+ pub fn derive_bitflags_from_str ( item : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
48+ from_str:: expand ( syn:: parse_macro_input!( item as syn:: DeriveInput ) ) . unwrap_or_compile_error ( )
49+ }
50+
2751trait ResultExt {
2852 fn unwrap_or_compile_error ( self ) -> proc_macro:: TokenStream ;
2953}
Original file line number Diff line number Diff line change @@ -22,18 +22,27 @@ extern crate bitflags;
2222#[macro_use]
2323extern crate bitflags_derive;
2424
25+ # fn main() -> Result<(), bitflags::parser::ParseError> {
2526bitflags! {
26- #[derive(FlagsDebug )]
27- struct Flags : u8 {
27+ #[derive(FlagsDisplay, FlagsFromStr )]
28+ struct MyFlags : u8 {
2829 const A = 1;
2930 const B = 1 << 1;
3031 const C = 1 << 2;
3132 }
3233}
33- # fn main() {}
34+
35+ let flags = "A | B".parse::<MyFlags>()?;
36+
37+ assert_eq!("A | B", flags.to_string());
38+ # Ok(())
39+ # }
3440```
41+
42+ These derives work for any type that implements the [`Flags`](https://docs.rs/bitflags/latest/bitflags/trait.Flags.html) trait.
3543*/
3644
45+ #![ no_std]
3746#![ deny( missing_docs) ]
3847
3948#[ doc( inline) ]
Original file line number Diff line number Diff line change 1+ #[ test]
2+ fn derive_display ( ) {
3+ bitflags ! {
4+ #[ derive( FlagsDisplay ) ]
5+ struct Flags : u8 {
6+ const A = 1 ;
7+ const B = 1 << 1 ;
8+ const C = 1 << 2 ;
9+ }
10+ }
11+
12+ assert_eq ! ( "A | B" , ( Flags :: A | Flags :: B ) . to_string( ) ) ;
13+ }
Original file line number Diff line number Diff line change 1+ #[ test]
2+ fn derive_from_str ( ) {
3+ bitflags ! {
4+ #[ derive( FlagsFromStr , PartialEq , Eq , Debug ) ]
5+ struct Flags : u8 {
6+ const A = 1 ;
7+ const B = 1 << 1 ;
8+ const C = 1 << 2 ;
9+ }
10+ }
11+
12+ assert_eq ! ( "A | B" . parse:: <Flags >( ) . unwrap( ) , Flags :: A | Flags :: B ) ;
13+ }
Original file line number Diff line number Diff line change @@ -7,3 +7,5 @@ extern crate bitflags;
77extern crate bitflags_derive;
88
99mod debug;
10+ mod display;
11+ mod from_str;
You can’t perform that action at this time.
0 commit comments