From 0207f5e1e0647a1f8c3a7399ac8f53eaf5432be0 Mon Sep 17 00:00:00 2001 From: Kevin Amado Date: Tue, 2 Apr 2024 15:50:22 -0600 Subject: [PATCH] dedup dependencies --- macros/src/deps.rs | 58 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/macros/src/deps.rs b/macros/src/deps.rs index 67305394..0b86b8b1 100644 --- a/macros/src/deps.rs +++ b/macros/src/deps.rs @@ -1,54 +1,84 @@ +use std::collections::HashSet; + use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use syn::{Path, Type}; pub struct Dependencies { - dependencies: Vec, crate_rename: Path, + dependencies: HashSet, pub types: Vec, } +#[derive(Hash, Eq, PartialEq)] +enum Operation { + ExtendByDependencyTypes { crate_rename: Path, ty: Type }, + ExtendGenerics { crate_rename: Path, ty: Type }, + PushType(Type), +} + impl Dependencies { pub fn new(crate_rename: Path) -> Self { Self { - dependencies: Vec::default(), + dependencies: HashSet::default(), crate_rename, types: Vec::default(), } } + /// Adds all dependencies from the given type pub fn append_from(&mut self, ty: &Type) { - let crate_rename = &self.crate_rename; self.dependencies - .push(quote![.extend(<#ty as #crate_rename::TS>::dependency_types())]); + .insert(Operation::ExtendByDependencyTypes { + crate_rename: self.crate_rename.clone(), + ty: ty.clone(), + }); + self.types.push(ty.clone()); } /// Adds the given type. pub fn push(&mut self, ty: &Type) { - let crate_rename = &self.crate_rename; - self.dependencies.push(quote![.push::<#ty>()]); - self.dependencies.push(quote![ - .extend(<#ty as #crate_rename::TS>::generics()) - ]); + self.dependencies.insert(Operation::PushType(ty.clone())); + self.dependencies.insert(Operation::ExtendGenerics { + crate_rename: self.crate_rename.clone(), + ty: ty.clone(), + }); self.types.push(ty.clone()); } pub fn append(&mut self, mut other: Dependencies) { - if !other.dependencies.is_empty() { - self.dependencies.push(quote![.extend(#other)]); + self.dependencies.extend(other.dependencies); + + if !other.types.is_empty() { + self.types.append(&mut other.types); } - self.types.append(&mut other.types); } } impl ToTokens for Dependencies { fn to_tokens(&self, tokens: &mut TokenStream) { let crate_rename = &self.crate_rename; - let lines = &self.dependencies; + + let lines = self + .dependencies + .iter() + .map(|operation| match operation { + Operation::PushType(ty) => quote![.push::<#ty>()], + Operation::ExtendByDependencyTypes { crate_rename, ty } => { + quote![.extend(<#ty as #crate_rename::TS>::dependency_types())] + } + Operation::ExtendGenerics { crate_rename, ty } => { + quote![ + .extend(<#ty as #crate_rename::TS>::generics()) + ] + } + }) + .collect::>(); + tokens.extend(quote![{ use #crate_rename::typelist::TypeList; ()#(#lines)* - }]) + }]); } }