@@ -10,6 +10,7 @@ mod kw {
10
10
syn:: custom_keyword!( MAX ) ;
11
11
syn:: custom_keyword!( ENCODABLE ) ;
12
12
syn:: custom_keyword!( custom) ;
13
+ syn:: custom_keyword!( ORD_IMPL ) ;
13
14
}
14
15
15
16
#[ derive( Debug ) ]
@@ -42,6 +43,7 @@ impl Parse for Newtype {
42
43
let mut max = None ;
43
44
let mut consts = Vec :: new ( ) ;
44
45
let mut encodable = true ;
46
+ let mut ord = true ;
45
47
46
48
// Parse an optional trailing comma
47
49
let try_comma = || -> Result < ( ) > {
@@ -99,13 +101,20 @@ impl Parse for Newtype {
99
101
encodable = false ;
100
102
continue ;
101
103
}
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
+ }
102
111
103
112
// We've parsed everything that the user provided, so we're done
104
113
if body. is_empty ( ) {
105
114
break ;
106
115
}
107
116
108
- // Otherwise, we are parsng a user-defined constant
117
+ // Otherwise, we are parsing a user-defined constant
109
118
let const_attrs = body. call ( Attribute :: parse_outer) ?;
110
119
body. parse :: < Token ! [ const ] > ( ) ?;
111
120
let const_name: Ident = body. parse ( ) ?;
@@ -137,6 +146,40 @@ impl Parse for Newtype {
137
146
quote ! { }
138
147
} ;
139
148
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
+
140
183
let debug_impl = match debug_format {
141
184
DebugFormat :: Custom => quote ! { } ,
142
185
DebugFormat :: Format ( format) => {
@@ -152,7 +195,7 @@ impl Parse for Newtype {
152
195
153
196
Ok ( Self ( quote ! {
154
197
#( #attrs) *
155
- #[ derive( Clone , Copy , PartialEq , Eq , Hash , PartialOrd , Ord , #( #derive_paths) , * ) ]
198
+ #[ derive( Clone , Copy , PartialEq , Eq , Hash , #( #derive_paths) , * ) ]
156
199
#[ rustc_layout_scalar_valid_range_end( #max) ]
157
200
#vis struct #name {
158
201
private: u32 ,
@@ -247,28 +290,7 @@ impl Parse for Newtype {
247
290
}
248
291
}
249
292
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
272
294
273
295
impl From <#name> for u32 {
274
296
#[ inline]
0 commit comments