blob: 8feb87cf013fc111b6682b3994885ee1d5d31aa8 [file] [log] [blame]
David Tolnaydaaf7742016-10-03 11:11:43 -07001use {Generics, Ident, LifetimeDef, TyParam, WhereClause, WherePredicate};
David Tolnay55337722016-09-11 12:58:56 -07002use aster::invoke::{Identity, Invoke};
3use aster::lifetime::{IntoLifetime, LifetimeDefBuilder, IntoLifetimeDef};
4use aster::path::IntoPath;
5use aster::ty_param::TyParamBuilder;
6use aster::where_predicate::WherePredicateBuilder;
7
David Tolnaydaaf7742016-10-03 11:11:43 -07008pub struct GenericsBuilder<F = Identity> {
David Tolnay55337722016-09-11 12:58:56 -07009 callback: F,
10 lifetimes: Vec<LifetimeDef>,
11 ty_params: Vec<TyParam>,
12 predicates: Vec<WherePredicate>,
13}
14
15impl GenericsBuilder {
16 pub fn new() -> Self {
17 GenericsBuilder::with_callback(Identity)
18 }
19
20 pub fn from_generics(generics: Generics) -> Self {
21 GenericsBuilder::from_generics_with_callback(generics, Identity)
22 }
23}
24
25impl<F> GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070026 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -070027{
28 pub fn with_callback(callback: F) -> Self {
29 GenericsBuilder {
30 callback: callback,
31 lifetimes: Vec::new(),
32 ty_params: Vec::new(),
33 predicates: Vec::new(),
34 }
35 }
36
37 pub fn from_generics_with_callback(generics: Generics, callback: F) -> Self {
38 GenericsBuilder {
39 callback: callback,
40 lifetimes: generics.lifetimes,
41 ty_params: generics.ty_params,
42 predicates: generics.where_clause.predicates,
43 }
44 }
45
46 pub fn with(self, generics: Generics) -> Self {
47 self.with_lifetimes(generics.lifetimes.into_iter())
48 .with_ty_params(generics.ty_params.into_iter())
49 .with_predicates(generics.where_clause.predicates.into_iter())
50 }
51
52 pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070053 where I: IntoIterator<Item = L>,
54 L: IntoLifetimeDef
David Tolnay55337722016-09-11 12:58:56 -070055 {
56 let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def());
57 self.lifetimes.extend(iter);
58 self
59 }
60
61 pub fn with_lifetime_names<I, N>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070062 where I: IntoIterator<Item = N>,
63 N: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070064 {
65 for name in iter {
66 self = self.lifetime_name(name);
67 }
68 self
69 }
70
71 pub fn with_lifetime(mut self, lifetime: LifetimeDef) -> Self {
72 self.lifetimes.push(lifetime);
73 self
74 }
75
76 pub fn lifetime_name<N>(self, name: N) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070077 where N: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070078 {
79 self.lifetime(name).build()
80 }
81
82 pub fn lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
David Tolnaydaaf7742016-10-03 11:11:43 -070083 where N: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070084 {
85 LifetimeDefBuilder::with_callback(name, self)
86 }
87
88 pub fn with_ty_params<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070089 where I: IntoIterator<Item = TyParam>
David Tolnay55337722016-09-11 12:58:56 -070090 {
91 self.ty_params.extend(iter);
92 self
93 }
94
95 pub fn with_ty_param_ids<I, T>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070096 where I: IntoIterator<Item = T>,
97 T: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070098 {
99 for id in iter {
100 self = self.ty_param_id(id);
101 }
102 self
103 }
104
105 pub fn with_ty_param(mut self, ty_param: TyParam) -> Self {
106 self.ty_params.push(ty_param);
107 self
108 }
109
110 pub fn ty_param_id<I>(self, id: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700111 where I: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -0700112 {
113 self.ty_param(id).build()
114 }
115
116 pub fn ty_param<I>(self, id: I) -> TyParamBuilder<Self>
David Tolnaydaaf7742016-10-03 11:11:43 -0700117 where I: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -0700118 {
119 TyParamBuilder::with_callback(id, self)
120 }
121
122 pub fn with_predicates<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700123 where I: IntoIterator<Item = WherePredicate>
David Tolnay55337722016-09-11 12:58:56 -0700124 {
125 self.predicates.extend(iter);
126 self
127 }
128
129 pub fn with_predicate(mut self, predicate: WherePredicate) -> Self {
130 self.predicates.push(predicate);
131 self
132 }
133
134 pub fn predicate(self) -> WherePredicateBuilder<Self> {
135 WherePredicateBuilder::with_callback(self)
136 }
137
138 pub fn add_lifetime_bound<L>(mut self, lifetime: L) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700139 where L: IntoLifetime
David Tolnay55337722016-09-11 12:58:56 -0700140 {
141 let lifetime = lifetime.into_lifetime();
142
143 for lifetime_def in &mut self.lifetimes {
144 lifetime_def.bounds.push(lifetime.clone());
145 }
146
147 for ty_param in &mut self.ty_params {
148 *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
149 .lifetime_bound(lifetime.clone())
150 .build();
151 }
152
153 self
154 }
155
156 pub fn add_ty_param_bound<P>(mut self, path: P) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700157 where P: IntoPath
David Tolnay55337722016-09-11 12:58:56 -0700158 {
159 let path = path.into_path();
160
161 for ty_param in &mut self.ty_params {
162 *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
David Tolnaydaaf7742016-10-03 11:11:43 -0700163 .trait_bound(path.clone())
164 .build()
David Tolnay55337722016-09-11 12:58:56 -0700165 .build();
166 }
167
168 self
169 }
170
171 pub fn strip_bounds(self) -> Self {
172 self.strip_lifetimes()
173 .strip_ty_params()
174 .strip_predicates()
175 }
176
177 pub fn strip_lifetimes(mut self) -> Self {
178 for lifetime in &mut self.lifetimes {
179 lifetime.bounds = vec![];
180 }
181 self
182 }
183
184 pub fn strip_ty_params(mut self) -> Self {
185 for ty_param in &mut self.ty_params {
186 ty_param.bounds = vec![];
187 }
188 self
189 }
190
191 pub fn strip_predicates(mut self) -> Self {
192 self.predicates = vec![];
193 self
194 }
195
196 pub fn build(self) -> F::Result {
197 self.callback.invoke(Generics {
198 lifetimes: self.lifetimes,
199 ty_params: self.ty_params,
David Tolnaydaaf7742016-10-03 11:11:43 -0700200 where_clause: WhereClause { predicates: self.predicates },
David Tolnay55337722016-09-11 12:58:56 -0700201 })
202 }
203}
204
205impl<F> Invoke<LifetimeDef> for GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700206 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -0700207{
208 type Result = Self;
209
210 fn invoke(self, lifetime: LifetimeDef) -> Self {
211 self.with_lifetime(lifetime)
212 }
213}
214
215impl<F> Invoke<TyParam> for GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700216 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -0700217{
218 type Result = Self;
219
220 fn invoke(self, ty_param: TyParam) -> Self {
221 self.with_ty_param(ty_param)
222 }
223}
224
225impl<F> Invoke<WherePredicate> for GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700226 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -0700227{
228 type Result = Self;
229
230 fn invoke(self, predicate: WherePredicate) -> Self {
231 self.with_predicate(predicate)
232 }
233}