@@ -40,39 +40,80 @@ impl Idx for u32 {
4040
4141#[ macro_export]
4242macro_rules! newtype_index {
43+ // ---- public rules ----
44+
45+ // Use default constants
4346 ( $name: ident) => (
44- newtype_index!( $name, unsafe { :: std:: intrinsics:: type_name:: <$name>( ) } ) ;
47+ newtype_index!(
48+ @type [ $name]
49+ @max[ :: std:: u32 :: MAX ]
50+ @debug_name[ unsafe { :: std:: intrinsics:: type_name:: <$name>( ) } ] ) ;
51+ ) ;
52+
53+ // Define any constants
54+ ( $name: ident { $( $tokens: tt) + } ) => (
55+ newtype_index!(
56+ @type [ $name]
57+ @max[ :: std:: u32 :: MAX ]
58+ @debug_name[ unsafe { :: std:: intrinsics:: type_name:: <$name>( ) } ]
59+ $( $tokens) +) ;
4560 ) ;
4661
47- ( $name: ident, $debug_name: expr) => (
62+ // ---- private rules ----
63+
64+ // Base case, user-defined constants (if any) have already been defined
65+ ( @type [ $type: ident] @max[ $max: expr] @debug_name[ $debug_name: expr] ) => (
4866 #[ derive( Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ,
49- RustcEncodable , RustcDecodable ) ]
50- pub struct $name( u32 ) ;
51-
52- impl $name {
53- // HACK use for constants
54- #[ allow( unused) ]
55- const fn const_new( x: u32 ) -> Self {
56- $name( x)
57- }
58- }
67+ RustcEncodable , RustcDecodable ) ]
68+ pub struct $type( u32 ) ;
5969
60- impl Idx for $name {
70+ impl Idx for $type {
6171 fn new( value: usize ) -> Self {
62- assert!( value < ( :: std :: u32 :: MAX ) as usize ) ;
63- $name ( value as u32 )
72+ assert!( value < ( $max ) as usize ) ;
73+ $type ( value as u32 )
6474 }
6575 fn index( self ) -> usize {
6676 self . 0 as usize
6777 }
6878 }
6979
70- impl :: std:: fmt:: Debug for $name {
80+ impl :: std:: fmt:: Debug for $type {
7181 fn fmt( & self , fmt: & mut :: std:: fmt:: Formatter ) -> :: std:: fmt:: Result {
7282 write!( fmt, "{}{}" , $debug_name, self . 0 )
7383 }
7484 }
75- )
85+ ) ;
86+
87+ // Rewrite final without comma to one that includes comma
88+ ( @type [ $type: ident] @max[ $max: expr] @debug_name[ $debug_name: expr]
89+ $name: ident = $constant: expr) => (
90+ newtype_index!( @type [ $type] @max[ $max] @debug_name[ $debug_name] $name = $constant, ) ;
91+ ) ;
92+
93+ // Rewrite final const without comma to one that includes comma
94+ ( @type [ $type: ident] @max[ $_max: expr] @debug_name[ $debug_name: expr]
95+ const $name: ident = $constant: expr) => (
96+ newtype_index!( @type [ $type] @max[ $max] @debug_name[ $debug_name] const $name = $constant, ) ;
97+ ) ;
98+
99+ // Replace existing default for max
100+ ( @type [ $type: ident] @max[ $_max: expr] @debug_name[ $debug_name: expr]
101+ MAX = $max: expr, $( $tokens: tt) * ) => (
102+ newtype_index!( @type [ $type] @max[ $max] @debug_name[ $debug_name] $( tokens) * ) ;
103+ ) ;
104+
105+ // Replace existing default for debug_name
106+ ( @type [ $type: ident] @max[ $max: expr] @debug_name[ $_debug_name: expr]
107+ DEBUG_NAME = $debug_name: expr, $( $tokens: tt) * ) => (
108+ newtype_index!( @type [ $type] @max[ $max] @debug_name[ $debug_name] $( $tokens) * ) ;
109+ ) ;
110+
111+ // Assign a user-defined constant (as final param)
112+ ( @type [ $type: ident] @max[ $max: expr] @debug_name[ $debug_name: expr]
113+ const $name: ident = $constant: expr, $( $tokens: tt) * ) => (
114+ pub const $name: $type = $type( $constant) ;
115+ newtype_index!( @type [ $type] @max[ $max] @debug_name[ $debug_name] $( $tokens) * ) ;
116+ ) ;
76117}
77118
78119#[ derive( Clone , PartialEq , Eq ) ]
0 commit comments