Skip to content

Commit

Permalink
Implement trait generics on impl-for
Browse files Browse the repository at this point in the history
  • Loading branch information
NightEule5 committed Nov 10, 2023
1 parent f89b2b6 commit 5a4f7c7
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions src/generate/impl_for.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct ImplFor<'a, P: Parent> {
type_name: StringOrIdent,
trait_name: Option<StringOrIdent>,
lifetimes: Option<Vec<String>>,
generics: Option<Vec<String>>,
consts: Vec<StreamBuilder>,
custom_generic_constraints: Option<GenericConstraints>,
impl_types: Vec<StreamBuilder>,
Expand All @@ -32,6 +33,7 @@ impl<'a, P: Parent> ImplFor<'a, P> {
trait_name,
type_name,
lifetimes: None,
generics: Vec::new(),

Check failure on line 36 in src/generate/impl_for.rs

View workflow job for this annotation

GitHub Actions / Check (stable)

mismatched types

Check failure on line 36 in src/generate/impl_for.rs

View workflow job for this annotation

GitHub Actions / Lints

mismatched types

Check failure on line 36 in src/generate/impl_for.rs

View workflow job for this annotation

GitHub Actions / Check (beta)

mismatched types

Check failure on line 36 in src/generate/impl_for.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

mismatched types
consts: Vec::new(),
custom_generic_constraints: None,
impl_types: Vec::new(),
Expand Down Expand Up @@ -77,6 +79,23 @@ impl<'a, P: Parent> ImplFor<'a, P> {
self
}

/// Add generic parameters to the trait.
///
/// `generator.impl_for("Foo").with_trait_generic(["Bar", "Baz"])` results in code like:
///
/// ```ignore
/// impl Foo<Bar, Baz> for <struct or enum> {
/// }
/// ```
pub fn with_trait_generics<ITER>(mut self, generics: ITER) -> Self
where
ITER: IntoIterator,
ITER::Item: Into<String>,
{
self.generics = Some(generics.into_iter().map(Into::into).collect());
self
}

/// Add a outer attribute to the trait implementation
pub fn impl_outer_attr(&mut self, attr: impl AsRef<str>) -> Result {
let mut builder = StreamBuilder::new();
Expand Down Expand Up @@ -266,9 +285,9 @@ impl<P: Parent> ImplFor<'_, P> {
}
if let Some(t) = &self.trait_name {
builder.push_parsed(t.to_string()).unwrap();
if let Some(lifetimes) = &self.lifetimes {
append_lifetimes(builder, lifetimes);
}
let lifetimes = self.lifetimes.as_deref().unwrap_or_default();
let generics = self.generics.as_deref().unwrap_or_default();
append_generics(builder, lifetimes, generics);
builder.ident_str("for");
}
builder.push_parsed(self.type_name.to_string()).unwrap();
Expand All @@ -283,10 +302,18 @@ impl<P: Parent> ImplFor<'_, P> {
}
}

fn append_lifetimes(builder: &mut StreamBuilder, lifetimes: &[String]) {
fn append_generics(builder: &mut StreamBuilder, lifetimes: &[String], generics: &[String]) {
for (idx, lt) in lifetimes.iter().enumerate() {
builder.punct(if idx == 0 { '<' } else { ',' });
builder.lifetime_str(lt);
}

for (idx, gen) in generics.iter().enumerate() {
if idx > 0 || !lifetimes.is_empty() {
builder.punct(',');
}
builder.ident_str(gen);
}

builder.punct('>');
}

0 comments on commit 5a4f7c7

Please sign in to comment.