blob: c3c48463578e8a6a921a398651eba6e83aa3e8ed [file] [log] [blame]
David Tolnay55337722016-09-11 12:58:56 -07001use {
2 Generics,
3 Ident,
4 LifetimeDef,
5 TyParam,
6 WhereClause,
7 WherePredicate,
8};
9use aster::invoke::{Identity, Invoke};
10use aster::lifetime::{IntoLifetime, LifetimeDefBuilder, IntoLifetimeDef};
11use aster::path::IntoPath;
12use aster::ty_param::TyParamBuilder;
13use aster::where_predicate::WherePredicateBuilder;
14
15pub struct GenericsBuilder<F=Identity> {
16 callback: F,
17 lifetimes: Vec<LifetimeDef>,
18 ty_params: Vec<TyParam>,
19 predicates: Vec<WherePredicate>,
20}
21
22impl GenericsBuilder {
23 pub fn new() -> Self {
24 GenericsBuilder::with_callback(Identity)
25 }
26
27 pub fn from_generics(generics: Generics) -> Self {
28 GenericsBuilder::from_generics_with_callback(generics, Identity)
29 }
30}
31
32impl<F> GenericsBuilder<F>
33 where F: Invoke<Generics>,
34{
35 pub fn with_callback(callback: F) -> Self {
36 GenericsBuilder {
37 callback: callback,
38 lifetimes: Vec::new(),
39 ty_params: Vec::new(),
40 predicates: Vec::new(),
41 }
42 }
43
44 pub fn from_generics_with_callback(generics: Generics, callback: F) -> Self {
45 GenericsBuilder {
46 callback: callback,
47 lifetimes: generics.lifetimes,
48 ty_params: generics.ty_params,
49 predicates: generics.where_clause.predicates,
50 }
51 }
52
53 pub fn with(self, generics: Generics) -> Self {
54 self.with_lifetimes(generics.lifetimes.into_iter())
55 .with_ty_params(generics.ty_params.into_iter())
56 .with_predicates(generics.where_clause.predicates.into_iter())
57 }
58
59 pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self
60 where I: IntoIterator<Item=L>,
61 L: IntoLifetimeDef,
62 {
63 let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def());
64 self.lifetimes.extend(iter);
65 self
66 }
67
68 pub fn with_lifetime_names<I, N>(mut self, iter: I) -> Self
69 where I: IntoIterator<Item=N>,
70 N: Into<Ident>,
71 {
72 for name in iter {
73 self = self.lifetime_name(name);
74 }
75 self
76 }
77
78 pub fn with_lifetime(mut self, lifetime: LifetimeDef) -> Self {
79 self.lifetimes.push(lifetime);
80 self
81 }
82
83 pub fn lifetime_name<N>(self, name: N) -> Self
84 where N: Into<Ident>,
85 {
86 self.lifetime(name).build()
87 }
88
89 pub fn lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
90 where N: Into<Ident>,
91 {
92 LifetimeDefBuilder::with_callback(name, self)
93 }
94
95 pub fn with_ty_params<I>(mut self, iter: I) -> Self
96 where I: IntoIterator<Item=TyParam>,
97 {
98 self.ty_params.extend(iter);
99 self
100 }
101
102 pub fn with_ty_param_ids<I, T>(mut self, iter: I) -> Self
103 where I: IntoIterator<Item=T>,
104 T: Into<Ident>,
105 {
106 for id in iter {
107 self = self.ty_param_id(id);
108 }
109 self
110 }
111
112 pub fn with_ty_param(mut self, ty_param: TyParam) -> Self {
113 self.ty_params.push(ty_param);
114 self
115 }
116
117 pub fn ty_param_id<I>(self, id: I) -> Self
118 where I: Into<Ident>,
119 {
120 self.ty_param(id).build()
121 }
122
123 pub fn ty_param<I>(self, id: I) -> TyParamBuilder<Self>
124 where I: Into<Ident>,
125 {
126 TyParamBuilder::with_callback(id, self)
127 }
128
129 pub fn with_predicates<I>(mut self, iter: I) -> Self
130 where I: IntoIterator<Item=WherePredicate>,
131 {
132 self.predicates.extend(iter);
133 self
134 }
135
136 pub fn with_predicate(mut self, predicate: WherePredicate) -> Self {
137 self.predicates.push(predicate);
138 self
139 }
140
141 pub fn predicate(self) -> WherePredicateBuilder<Self> {
142 WherePredicateBuilder::with_callback(self)
143 }
144
145 pub fn add_lifetime_bound<L>(mut self, lifetime: L) -> Self
146 where L: IntoLifetime,
147 {
148 let lifetime = lifetime.into_lifetime();
149
150 for lifetime_def in &mut self.lifetimes {
151 lifetime_def.bounds.push(lifetime.clone());
152 }
153
154 for ty_param in &mut self.ty_params {
155 *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
156 .lifetime_bound(lifetime.clone())
157 .build();
158 }
159
160 self
161 }
162
163 pub fn add_ty_param_bound<P>(mut self, path: P) -> Self
164 where P: IntoPath,
165 {
166 let path = path.into_path();
167
168 for ty_param in &mut self.ty_params {
169 *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
170 .trait_bound(path.clone()).build()
171 .build();
172 }
173
174 self
175 }
176
177 pub fn strip_bounds(self) -> Self {
178 self.strip_lifetimes()
179 .strip_ty_params()
180 .strip_predicates()
181 }
182
183 pub fn strip_lifetimes(mut self) -> Self {
184 for lifetime in &mut self.lifetimes {
185 lifetime.bounds = vec![];
186 }
187 self
188 }
189
190 pub fn strip_ty_params(mut self) -> Self {
191 for ty_param in &mut self.ty_params {
192 ty_param.bounds = vec![];
193 }
194 self
195 }
196
197 pub fn strip_predicates(mut self) -> Self {
198 self.predicates = vec![];
199 self
200 }
201
202 pub fn build(self) -> F::Result {
203 self.callback.invoke(Generics {
204 lifetimes: self.lifetimes,
205 ty_params: self.ty_params,
206 where_clause: WhereClause {
207 predicates: self.predicates,
208 },
209 })
210 }
211}
212
213impl<F> Invoke<LifetimeDef> for GenericsBuilder<F>
214 where F: Invoke<Generics>,
215{
216 type Result = Self;
217
218 fn invoke(self, lifetime: LifetimeDef) -> Self {
219 self.with_lifetime(lifetime)
220 }
221}
222
223impl<F> Invoke<TyParam> for GenericsBuilder<F>
224 where F: Invoke<Generics>,
225{
226 type Result = Self;
227
228 fn invoke(self, ty_param: TyParam) -> Self {
229 self.with_ty_param(ty_param)
230 }
231}
232
233impl<F> Invoke<WherePredicate> for GenericsBuilder<F>
234 where F: Invoke<Generics>,
235{
236 type Result = Self;
237
238 fn invoke(self, predicate: WherePredicate) -> Self {
239 self.with_predicate(predicate)
240 }
241}