| use {Generics, Ident, LifetimeDef, TyParam, WhereClause, WherePredicate}; |
| use aster::invoke::{Identity, Invoke}; |
| use aster::lifetime::{IntoLifetime, LifetimeDefBuilder, IntoLifetimeDef}; |
| use aster::path::IntoPath; |
| use aster::ty_param::TyParamBuilder; |
| use aster::where_predicate::WherePredicateBuilder; |
| |
| pub struct GenericsBuilder<F = Identity> { |
| callback: F, |
| lifetimes: Vec<LifetimeDef>, |
| ty_params: Vec<TyParam>, |
| predicates: Vec<WherePredicate>, |
| } |
| |
| impl GenericsBuilder { |
| pub fn new() -> Self { |
| GenericsBuilder::with_callback(Identity) |
| } |
| |
| pub fn from_generics(generics: Generics) -> Self { |
| GenericsBuilder::from_generics_with_callback(generics, Identity) |
| } |
| } |
| |
| impl<F> GenericsBuilder<F> |
| where F: Invoke<Generics> |
| { |
| pub fn with_callback(callback: F) -> Self { |
| GenericsBuilder { |
| callback: callback, |
| lifetimes: Vec::new(), |
| ty_params: Vec::new(), |
| predicates: Vec::new(), |
| } |
| } |
| |
| pub fn from_generics_with_callback(generics: Generics, callback: F) -> Self { |
| GenericsBuilder { |
| callback: callback, |
| lifetimes: generics.lifetimes, |
| ty_params: generics.ty_params, |
| predicates: generics.where_clause.predicates, |
| } |
| } |
| |
| pub fn with(self, generics: Generics) -> Self { |
| self.with_lifetimes(generics.lifetimes.into_iter()) |
| .with_ty_params(generics.ty_params.into_iter()) |
| .with_predicates(generics.where_clause.predicates.into_iter()) |
| } |
| |
| pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self |
| where I: IntoIterator<Item = L>, |
| L: IntoLifetimeDef |
| { |
| let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def()); |
| self.lifetimes.extend(iter); |
| self |
| } |
| |
| pub fn with_lifetime_names<I, N>(mut self, iter: I) -> Self |
| where I: IntoIterator<Item = N>, |
| N: Into<Ident> |
| { |
| for name in iter { |
| self = self.lifetime_name(name); |
| } |
| self |
| } |
| |
| pub fn with_lifetime(mut self, lifetime: LifetimeDef) -> Self { |
| self.lifetimes.push(lifetime); |
| self |
| } |
| |
| pub fn lifetime_name<N>(self, name: N) -> Self |
| where N: Into<Ident> |
| { |
| self.lifetime(name).build() |
| } |
| |
| pub fn lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self> |
| where N: Into<Ident> |
| { |
| LifetimeDefBuilder::with_callback(name, self) |
| } |
| |
| pub fn with_ty_params<I>(mut self, iter: I) -> Self |
| where I: IntoIterator<Item = TyParam> |
| { |
| self.ty_params.extend(iter); |
| self |
| } |
| |
| pub fn with_ty_param_ids<I, T>(mut self, iter: I) -> Self |
| where I: IntoIterator<Item = T>, |
| T: Into<Ident> |
| { |
| for id in iter { |
| self = self.ty_param_id(id); |
| } |
| self |
| } |
| |
| pub fn with_ty_param(mut self, ty_param: TyParam) -> Self { |
| self.ty_params.push(ty_param); |
| self |
| } |
| |
| pub fn ty_param_id<I>(self, id: I) -> Self |
| where I: Into<Ident> |
| { |
| self.ty_param(id).build() |
| } |
| |
| pub fn ty_param<I>(self, id: I) -> TyParamBuilder<Self> |
| where I: Into<Ident> |
| { |
| TyParamBuilder::with_callback(id, self) |
| } |
| |
| pub fn with_predicates<I>(mut self, iter: I) -> Self |
| where I: IntoIterator<Item = WherePredicate> |
| { |
| self.predicates.extend(iter); |
| self |
| } |
| |
| pub fn with_predicate(mut self, predicate: WherePredicate) -> Self { |
| self.predicates.push(predicate); |
| self |
| } |
| |
| pub fn predicate(self) -> WherePredicateBuilder<Self> { |
| WherePredicateBuilder::with_callback(self) |
| } |
| |
| pub fn add_lifetime_bound<L>(mut self, lifetime: L) -> Self |
| where L: IntoLifetime |
| { |
| let lifetime = lifetime.into_lifetime(); |
| |
| for lifetime_def in &mut self.lifetimes { |
| lifetime_def.bounds.push(lifetime.clone()); |
| } |
| |
| for ty_param in &mut self.ty_params { |
| *ty_param = TyParamBuilder::from_ty_param(ty_param.clone()) |
| .lifetime_bound(lifetime.clone()) |
| .build(); |
| } |
| |
| self |
| } |
| |
| pub fn add_ty_param_bound<P>(mut self, path: P) -> Self |
| where P: IntoPath |
| { |
| let path = path.into_path(); |
| |
| for ty_param in &mut self.ty_params { |
| *ty_param = TyParamBuilder::from_ty_param(ty_param.clone()) |
| .trait_bound(path.clone()) |
| .build() |
| .build(); |
| } |
| |
| self |
| } |
| |
| pub fn strip_bounds(self) -> Self { |
| self.strip_lifetimes() |
| .strip_ty_params() |
| .strip_predicates() |
| } |
| |
| pub fn strip_lifetimes(mut self) -> Self { |
| for lifetime in &mut self.lifetimes { |
| lifetime.bounds = vec![]; |
| } |
| self |
| } |
| |
| pub fn strip_ty_params(mut self) -> Self { |
| for ty_param in &mut self.ty_params { |
| ty_param.bounds = vec![]; |
| } |
| self |
| } |
| |
| pub fn strip_predicates(mut self) -> Self { |
| self.predicates = vec![]; |
| self |
| } |
| |
| pub fn build(self) -> F::Result { |
| self.callback.invoke(Generics { |
| lifetimes: self.lifetimes, |
| ty_params: self.ty_params, |
| where_clause: WhereClause { predicates: self.predicates }, |
| }) |
| } |
| } |
| |
| impl<F> Invoke<LifetimeDef> for GenericsBuilder<F> |
| where F: Invoke<Generics> |
| { |
| type Result = Self; |
| |
| fn invoke(self, lifetime: LifetimeDef) -> Self { |
| self.with_lifetime(lifetime) |
| } |
| } |
| |
| impl<F> Invoke<TyParam> for GenericsBuilder<F> |
| where F: Invoke<Generics> |
| { |
| type Result = Self; |
| |
| fn invoke(self, ty_param: TyParam) -> Self { |
| self.with_ty_param(ty_param) |
| } |
| } |
| |
| impl<F> Invoke<WherePredicate> for GenericsBuilder<F> |
| where F: Invoke<Generics> |
| { |
| type Result = Self; |
| |
| fn invoke(self, predicate: WherePredicate) -> Self { |
| self.with_predicate(predicate) |
| } |
| } |