@@ -13,7 +13,8 @@ pub struct ImplFor<'a, P: Parent> {
13
13
type_name : StringOrIdent ,
14
14
trait_name : Option < StringOrIdent > ,
15
15
lifetimes : Option < Vec < String > > ,
16
- generics : Option < Vec < String > > ,
16
+ trait_generics : Option < Vec < String > > ,
17
+ impl_generics : Vec < String > ,
17
18
consts : Vec < StreamBuilder > ,
18
19
custom_generic_constraints : Option < GenericConstraints > ,
19
20
impl_types : Vec < StreamBuilder > ,
@@ -33,7 +34,8 @@ impl<'a, P: Parent> ImplFor<'a, P> {
33
34
trait_name,
34
35
type_name,
35
36
lifetimes : None ,
36
- generics : None ,
37
+ trait_generics : None ,
38
+ impl_generics : vec ! [ ] ,
37
39
consts : Vec :: new ( ) ,
38
40
custom_generic_constraints : None ,
39
41
impl_types : Vec :: new ( ) ,
@@ -100,7 +102,30 @@ impl<'a, P: Parent> ImplFor<'a, P> {
100
102
ITER : IntoIterator ,
101
103
ITER :: Item : Into < String > ,
102
104
{
103
- self . generics = Some ( generics. into_iter ( ) . map ( Into :: into) . collect ( ) ) ;
105
+ self . trait_generics = Some ( generics. into_iter ( ) . map ( Into :: into) . collect ( ) ) ;
106
+ self
107
+ }
108
+
109
+ /// Add generic parameters to the impl block.
110
+ ///```
111
+ /// # use virtue::prelude::Generator;
112
+ /// # let mut generator = Generator::with_name("Bar");
113
+ /// generator.impl_for("Foo")
114
+ /// .with_impl_generics(["Baz"]);
115
+ /// # generator.assert_eq("impl < Baz > Foo for Bar { }");
116
+ /// # Ok::<_, virtue::Error>(())
117
+ /// ```
118
+ ///
119
+ /// Generates:
120
+ /// ```ignore
121
+ /// impl<Baz> Foo for Bar { }
122
+ /// ```
123
+ pub fn with_impl_generics < ITER > ( mut self , generics : ITER ) -> Self
124
+ where
125
+ ITER : IntoIterator ,
126
+ ITER :: Item : Into < String > ,
127
+ {
128
+ self . impl_generics = generics. into_iter ( ) . map ( Into :: into) . collect ( ) ;
104
129
self
105
130
}
106
131
@@ -282,20 +307,24 @@ impl<P: Parent> Drop for ImplFor<'_, P> {
282
307
impl < P : Parent > ImplFor < ' _ , P > {
283
308
fn generate_impl_definition ( & mut self , builder : & mut StreamBuilder ) {
284
309
builder. ident_str ( "impl" ) ;
310
+
311
+ let impl_generics = self . impl_generics . as_slice ( ) ;
285
312
if let Some ( lifetimes) = & self . lifetimes {
286
313
if let Some ( generics) = self . generator . generics ( ) {
287
- builder. append ( generics. impl_generics_with_additional_lifetimes ( lifetimes) ) ;
314
+ builder. append ( generics. impl_generics_with_additional ( lifetimes, impl_generics ) ) ;
288
315
} else {
289
- append_lifetimes_and_generics ( builder, lifetimes, & [ ] ) ;
316
+ append_lifetimes_and_generics ( builder, lifetimes, impl_generics ) ;
290
317
}
291
318
} else if let Some ( generics) = self . generator . generics ( ) {
292
- builder. append ( generics. impl_generics ( ) ) ;
319
+ builder. append ( generics. impl_generics_with_additional ( & [ ] , impl_generics) ) ;
320
+ } else if !impl_generics. is_empty ( ) {
321
+ append_lifetimes_and_generics ( builder, & [ ] , impl_generics)
293
322
}
294
323
if let Some ( t) = & self . trait_name {
295
324
builder. push_parsed ( t. to_string ( ) ) . unwrap ( ) ;
296
325
297
326
let lifetimes = self . lifetimes . as_deref ( ) . unwrap_or_default ( ) ;
298
- let generics = self . generics . as_deref ( ) . unwrap_or_default ( ) ;
327
+ let generics = self . trait_generics . as_deref ( ) . unwrap_or_default ( ) ;
299
328
append_lifetimes_and_generics ( builder, lifetimes, generics) ;
300
329
builder. ident_str ( "for" ) ;
301
330
}
@@ -333,7 +362,7 @@ fn append_lifetimes_and_generics(
333
362
if idx > 0 || !lifetimes. is_empty ( ) {
334
363
builder. punct ( ',' ) ;
335
364
}
336
- builder. ident_str ( gen) ;
365
+ builder. push_parsed ( gen) . unwrap ( ) ;
337
366
}
338
367
339
368
builder. punct ( '>' ) ;
0 commit comments