@@ -10,6 +10,7 @@ mod kw {
1010 syn:: custom_keyword!( MAX ) ;
1111 syn:: custom_keyword!( ENCODABLE ) ;
1212 syn:: custom_keyword!( custom) ;
13+ syn:: custom_keyword!( ORD_IMPL ) ;
1314}
1415
1516#[ derive( Debug ) ]
@@ -42,6 +43,7 @@ impl Parse for Newtype {
4243 let mut max = None ;
4344 let mut consts = Vec :: new ( ) ;
4445 let mut encodable = true ;
46+ let mut ord = true ;
4547
4648 // Parse an optional trailing comma
4749 let try_comma = || -> Result < ( ) > {
@@ -99,13 +101,20 @@ impl Parse for Newtype {
99101 encodable = false ;
100102 continue ;
101103 }
104+ if body. lookahead1 ( ) . peek ( kw:: ORD_IMPL ) {
105+ body. parse :: < kw:: ORD_IMPL > ( ) ?;
106+ body. parse :: < Token ! [ =] > ( ) ?;
107+ body. parse :: < kw:: custom > ( ) ?;
108+ ord = false ;
109+ continue ;
110+ }
102111
103112 // We've parsed everything that the user provided, so we're done
104113 if body. is_empty ( ) {
105114 break ;
106115 }
107116
108- // Otherwise, we are parsng a user-defined constant
117+ // Otherwise, we are parsing a user-defined constant
109118 let const_attrs = body. call ( Attribute :: parse_outer) ?;
110119 body. parse :: < Token ! [ const ] > ( ) ?;
111120 let const_name: Ident = body. parse ( ) ?;
@@ -137,6 +146,40 @@ impl Parse for Newtype {
137146 quote ! { }
138147 } ;
139148
149+ if ord {
150+ derive_paths. push ( parse_quote ! ( Ord ) ) ;
151+ derive_paths. push ( parse_quote ! ( PartialOrd ) ) ;
152+ }
153+
154+ let step = if ord {
155+ quote ! {
156+ impl :: std:: iter:: Step for #name {
157+ #[ inline]
158+ fn steps_between( start: & Self , end: & Self ) -> Option <usize > {
159+ <usize as :: std:: iter:: Step >:: steps_between(
160+ & Self :: index( * start) ,
161+ & Self :: index( * end) ,
162+ )
163+ }
164+
165+ #[ inline]
166+ fn forward_checked( start: Self , u: usize ) -> Option <Self > {
167+ Self :: index( start) . checked_add( u) . map( Self :: from_usize)
168+ }
169+
170+ #[ inline]
171+ fn backward_checked( start: Self , u: usize ) -> Option <Self > {
172+ Self :: index( start) . checked_sub( u) . map( Self :: from_usize)
173+ }
174+ }
175+
176+ // Safety: The implementation of `Step` upholds all invariants.
177+ unsafe impl :: std:: iter:: TrustedStep for #name { }
178+ }
179+ } else {
180+ quote ! { }
181+ } ;
182+
140183 let debug_impl = match debug_format {
141184 DebugFormat :: Custom => quote ! { } ,
142185 DebugFormat :: Format ( format) => {
@@ -152,7 +195,7 @@ impl Parse for Newtype {
152195
153196 Ok ( Self ( quote ! {
154197 #( #attrs) *
155- #[ derive( Clone , Copy , PartialEq , Eq , Hash , PartialOrd , Ord , #( #derive_paths) , * ) ]
198+ #[ derive( Clone , Copy , PartialEq , Eq , Hash , #( #derive_paths) , * ) ]
156199 #[ rustc_layout_scalar_valid_range_end( #max) ]
157200 #vis struct #name {
158201 private: u32 ,
@@ -247,28 +290,7 @@ impl Parse for Newtype {
247290 }
248291 }
249292
250- impl :: std:: iter:: Step for #name {
251- #[ inline]
252- fn steps_between( start: & Self , end: & Self ) -> Option <usize > {
253- <usize as :: std:: iter:: Step >:: steps_between(
254- & Self :: index( * start) ,
255- & Self :: index( * end) ,
256- )
257- }
258-
259- #[ inline]
260- fn forward_checked( start: Self , u: usize ) -> Option <Self > {
261- Self :: index( start) . checked_add( u) . map( Self :: from_usize)
262- }
263-
264- #[ inline]
265- fn backward_checked( start: Self , u: usize ) -> Option <Self > {
266- Self :: index( start) . checked_sub( u) . map( Self :: from_usize)
267- }
268- }
269-
270- // Safety: The implementation of `Step` upholds all invariants.
271- unsafe impl :: std:: iter:: TrustedStep for #name { }
293+ #step
272294
273295 impl From <#name> for u32 {
274296 #[ inline]
0 commit comments