@@ -20,7 +20,7 @@ use crate::common::{
20
20
} ;
21
21
use proc_macro2:: { Punct , Spacing , TokenStream , TokenTree } ;
22
22
use quote:: { format_ident, quote, ToTokens } ;
23
- use syn:: Visibility ;
23
+ use syn:: { Generics , Visibility } ;
24
24
25
25
/// Inject an inner type into a closure, so compiler does not complain if the token stream matchers
26
26
/// the expected closure pattern.
@@ -133,9 +133,13 @@ pub fn gen_reimports(
133
133
}
134
134
}
135
135
136
- pub fn gen_impl_into_inner ( type_name : & TypeName , inner_type : impl ToTokens ) -> TokenStream {
136
+ pub fn gen_impl_into_inner (
137
+ type_name : & TypeName ,
138
+ generics : & Generics ,
139
+ inner_type : impl ToTokens ,
140
+ ) -> TokenStream {
137
141
quote ! {
138
- impl #type_name {
142
+ impl #generics # type_name #generics {
139
143
#[ inline]
140
144
pub fn into_inner( self ) -> #inner_type {
141
145
self . 0
@@ -178,6 +182,7 @@ pub trait GenerateNewtype {
178
182
179
183
fn gen_traits (
180
184
type_name : & TypeName ,
185
+ generics : & Generics ,
181
186
inner_type : & Self :: InnerType ,
182
187
maybe_error_type_name : Option < ErrorTypeName > ,
183
188
traits : HashSet < Self :: TypedTrait > ,
@@ -187,14 +192,15 @@ pub trait GenerateNewtype {
187
192
188
193
fn gen_new_with_validation (
189
194
type_name : & TypeName ,
195
+ generics : & Generics ,
190
196
inner_type : & Self :: InnerType ,
191
197
sanitizers : & [ Self :: Sanitizer ] ,
192
198
validators : & [ Self :: Validator ] ,
193
199
) -> TokenStream {
194
- let sanitize = Self :: gen_fn_sanitize ( inner_type, sanitizers) ;
200
+ let fn_sanitize = Self :: gen_fn_sanitize ( inner_type, sanitizers) ;
195
201
let validation_error = Self :: gen_validation_error_type ( type_name, validators) ;
196
202
let error_type_name = gen_error_type_name ( type_name) ;
197
- let validate = Self :: gen_fn_validate ( inner_type, type_name, validators) ;
203
+ let fn_validate = Self :: gen_fn_validate ( inner_type, type_name, validators) ;
198
204
199
205
let ( input_type, convert_raw_value_if_necessary) = if Self :: NEW_CONVERT_INTO_INNER_TYPE {
200
206
(
@@ -208,29 +214,30 @@ pub trait GenerateNewtype {
208
214
quote ! (
209
215
#validation_error
210
216
211
- impl #type_name {
217
+ impl #generics # type_name #generics {
212
218
pub fn new( raw_value: #input_type) -> :: core:: result:: Result <Self , #error_type_name> {
213
- // Keep sanitize() and validate() within new() so they do not overlap with outer
214
- // scope imported with `use super::*`.
215
- #sanitize
216
- #validate
217
-
218
219
#convert_raw_value_if_necessary
219
220
220
- let sanitized_value: #inner_type = sanitize ( raw_value) ;
221
- validate ( & sanitized_value) ?;
221
+ let sanitized_value: #inner_type = Self :: __sanitize__ ( raw_value) ;
222
+ Self :: __validate__ ( & sanitized_value) ?;
222
223
Ok ( #type_name( sanitized_value) )
223
224
}
225
+
226
+ // Definite associated private functions __sanitize__() and __validate__() with underscores so they do not overlap with outer
227
+ // scope imported with `use super::*`.
228
+ #fn_sanitize
229
+ #fn_validate
224
230
}
225
231
)
226
232
}
227
233
228
234
fn gen_new_without_validation (
229
235
type_name : & TypeName ,
236
+ generics : & Generics ,
230
237
inner_type : & Self :: InnerType ,
231
238
sanitizers : & [ Self :: Sanitizer ] ,
232
239
) -> TokenStream {
233
- let sanitize = Self :: gen_fn_sanitize ( inner_type, sanitizers) ;
240
+ let fn_sanitize = Self :: gen_fn_sanitize ( inner_type, sanitizers) ;
234
241
235
242
let ( input_type, convert_raw_value_if_necessary) = if Self :: NEW_CONVERT_INTO_INNER_TYPE {
236
243
(
@@ -242,34 +249,37 @@ pub trait GenerateNewtype {
242
249
} ;
243
250
244
251
quote ! (
245
- impl #type_name {
252
+ impl #generics # type_name #generics {
246
253
pub fn new( raw_value: #input_type) -> Self {
247
- #sanitize
248
-
249
254
#convert_raw_value_if_necessary
250
-
251
- Self ( sanitize( raw_value) )
255
+ Self ( Self :: __sanitize__( raw_value) )
252
256
}
257
+ // Definite associated private function __sanitize__() with underscores so they do not overlap with outer
258
+ // scope imported with `use super::*`.
259
+ #fn_sanitize
253
260
}
254
261
)
255
262
}
256
263
257
264
fn gen_implementation (
258
265
type_name : & TypeName ,
266
+ generics : & Generics ,
259
267
inner_type : & Self :: InnerType ,
260
268
guard : & Guard < Self :: Sanitizer , Self :: Validator > ,
261
269
new_unchecked : NewUnchecked ,
262
270
) -> TokenStream {
263
271
let impl_new = match guard {
264
272
Guard :: WithoutValidation { sanitizers } => {
265
- Self :: gen_new_without_validation ( type_name, inner_type, sanitizers)
273
+ Self :: gen_new_without_validation ( type_name, generics , inner_type, sanitizers)
266
274
}
267
275
Guard :: WithValidation {
268
276
sanitizers,
269
277
validators,
270
- } => Self :: gen_new_with_validation ( type_name, inner_type, sanitizers, validators) ,
278
+ } => Self :: gen_new_with_validation (
279
+ type_name, generics, inner_type, sanitizers, validators,
280
+ ) ,
271
281
} ;
272
- let impl_into_inner = gen_impl_into_inner ( type_name, inner_type) ;
282
+ let impl_into_inner = gen_impl_into_inner ( type_name, generics , inner_type) ;
273
283
let impl_new_unchecked = gen_new_unchecked ( type_name, inner_type, new_unchecked) ;
274
284
275
285
quote ! {
@@ -296,11 +306,12 @@ pub trait GenerateNewtype {
296
306
new_unchecked,
297
307
maybe_default_value,
298
308
inner_type,
309
+ generics,
299
310
} = params;
300
311
301
312
let module_name = gen_module_name_for_type ( & type_name) ;
302
313
let implementation =
303
- Self :: gen_implementation ( & type_name, & inner_type, & guard, new_unchecked) ;
314
+ Self :: gen_implementation ( & type_name, & generics , & inner_type, & guard, new_unchecked) ;
304
315
305
316
let maybe_error_type_name: Option < ErrorTypeName > = match guard {
306
317
Guard :: WithoutValidation { .. } => None ,
@@ -335,6 +346,7 @@ pub trait GenerateNewtype {
335
346
implement_traits,
336
347
} = Self :: gen_traits (
337
348
& type_name,
349
+ & generics,
338
350
& inner_type,
339
351
maybe_error_type_name,
340
352
traits,
@@ -349,7 +361,7 @@ pub trait GenerateNewtype {
349
361
350
362
#( #doc_attrs) *
351
363
#derive_transparent_traits
352
- pub struct #type_name( #inner_type) ;
364
+ pub struct #type_name #generics ( #inner_type) ;
353
365
354
366
#implementation
355
367
#implement_traits
0 commit comments