blob: 8cc84d0c09f165bc59f4a7f56566e96639e834f1 [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
Alex Crichtonccbb45d2017-05-23 10:58:24 -07008use delimited::Delimited;
9
David Tolnaydaaf7742016-10-03 11:11:43 -070010pub struct GenericsBuilder<F = Identity> {
David Tolnay55337722016-09-11 12:58:56 -070011 callback: F,
12 lifetimes: Vec<LifetimeDef>,
13 ty_params: Vec<TyParam>,
14 predicates: Vec<WherePredicate>,
15}
16
17impl GenericsBuilder {
18 pub fn new() -> Self {
19 GenericsBuilder::with_callback(Identity)
20 }
21
22 pub fn from_generics(generics: Generics) -> Self {
23 GenericsBuilder::from_generics_with_callback(generics, Identity)
24 }
25}
26
27impl<F> GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070028 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -070029{
30 pub fn with_callback(callback: F) -> Self {
31 GenericsBuilder {
32 callback: callback,
33 lifetimes: Vec::new(),
34 ty_params: Vec::new(),
35 predicates: Vec::new(),
36 }
37 }
38
39 pub fn from_generics_with_callback(generics: Generics, callback: F) -> Self {
40 GenericsBuilder {
41 callback: callback,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070042 lifetimes: generics.lifetimes.into_vec(),
43 ty_params: generics.ty_params.into_vec(),
44 predicates: generics.where_clause.predicates.into_vec(),
David Tolnay55337722016-09-11 12:58:56 -070045 }
46 }
47
48 pub fn with(self, generics: Generics) -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070049 self.with_lifetimes(generics.lifetimes.into_vec().into_iter())
50 .with_ty_params(generics.ty_params.into_vec().into_iter())
51 .with_predicates(generics.where_clause.predicates.into_vec().into_iter())
David Tolnay55337722016-09-11 12:58:56 -070052 }
53
54 pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070055 where I: IntoIterator<Item = L>,
56 L: IntoLifetimeDef
David Tolnay55337722016-09-11 12:58:56 -070057 {
58 let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def());
59 self.lifetimes.extend(iter);
60 self
61 }
62
63 pub fn with_lifetime_names<I, N>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070064 where I: IntoIterator<Item = N>,
65 N: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070066 {
67 for name in iter {
68 self = self.lifetime_name(name);
69 }
70 self
71 }
72
73 pub fn with_lifetime(mut self, lifetime: LifetimeDef) -> Self {
74 self.lifetimes.push(lifetime);
75 self
76 }
77
78 pub fn lifetime_name<N>(self, name: N) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070079 where N: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070080 {
81 self.lifetime(name).build()
82 }
83
84 pub fn lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
David Tolnaydaaf7742016-10-03 11:11:43 -070085 where N: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -070086 {
87 LifetimeDefBuilder::with_callback(name, self)
88 }
89
90 pub fn with_ty_params<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070091 where I: IntoIterator<Item = TyParam>
David Tolnay55337722016-09-11 12:58:56 -070092 {
93 self.ty_params.extend(iter);
94 self
95 }
96
97 pub fn with_ty_param_ids<I, T>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -070098 where I: IntoIterator<Item = T>,
99 T: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -0700100 {
101 for id in iter {
102 self = self.ty_param_id(id);
103 }
104 self
105 }
106
107 pub fn with_ty_param(mut self, ty_param: TyParam) -> Self {
108 self.ty_params.push(ty_param);
109 self
110 }
111
112 pub fn ty_param_id<I>(self, id: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700113 where I: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -0700114 {
115 self.ty_param(id).build()
116 }
117
118 pub fn ty_param<I>(self, id: I) -> TyParamBuilder<Self>
David Tolnaydaaf7742016-10-03 11:11:43 -0700119 where I: Into<Ident>
David Tolnay55337722016-09-11 12:58:56 -0700120 {
121 TyParamBuilder::with_callback(id, self)
122 }
123
124 pub fn with_predicates<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700125 where I: IntoIterator<Item = WherePredicate>
David Tolnay55337722016-09-11 12:58:56 -0700126 {
127 self.predicates.extend(iter);
128 self
129 }
130
131 pub fn with_predicate(mut self, predicate: WherePredicate) -> Self {
132 self.predicates.push(predicate);
133 self
134 }
135
136 pub fn predicate(self) -> WherePredicateBuilder<Self> {
137 WherePredicateBuilder::with_callback(self)
138 }
139
140 pub fn add_lifetime_bound<L>(mut self, lifetime: L) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700141 where L: IntoLifetime
David Tolnay55337722016-09-11 12:58:56 -0700142 {
143 let lifetime = lifetime.into_lifetime();
144
145 for lifetime_def in &mut self.lifetimes {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700146 lifetime_def.bounds.push_default(lifetime.clone());
David Tolnay55337722016-09-11 12:58:56 -0700147 }
148
149 for ty_param in &mut self.ty_params {
150 *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
151 .lifetime_bound(lifetime.clone())
152 .build();
153 }
154
155 self
156 }
157
158 pub fn add_ty_param_bound<P>(mut self, path: P) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700159 where P: IntoPath
David Tolnay55337722016-09-11 12:58:56 -0700160 {
161 let path = path.into_path();
162
163 for ty_param in &mut self.ty_params {
164 *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
David Tolnaydaaf7742016-10-03 11:11:43 -0700165 .trait_bound(path.clone())
166 .build()
David Tolnay55337722016-09-11 12:58:56 -0700167 .build();
168 }
169
170 self
171 }
172
173 pub fn strip_bounds(self) -> Self {
David Tolnay05120ef2017-03-12 18:29:26 -0700174 self.strip_lifetimes().strip_ty_params().strip_predicates()
David Tolnay55337722016-09-11 12:58:56 -0700175 }
176
177 pub fn strip_lifetimes(mut self) -> Self {
178 for lifetime in &mut self.lifetimes {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700179 lifetime.bounds = Delimited::new();
David Tolnay55337722016-09-11 12:58:56 -0700180 }
181 self
182 }
183
184 pub fn strip_ty_params(mut self) -> Self {
185 for ty_param in &mut self.ty_params {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700186 ty_param.bounds = Delimited::new();
David Tolnay55337722016-09-11 12:58:56 -0700187 }
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 {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700198 lifetimes: self.lifetimes.into(),
199 ty_params: self.ty_params.into(),
200 where_clause: WhereClause {
201 predicates: self.predicates.into(),
202 where_token: Default::default(),
203 },
204 lt_token: Default::default(),
205 gt_token: Default::default(),
206 })
David Tolnay55337722016-09-11 12:58:56 -0700207 }
208}
209
210impl<F> Invoke<LifetimeDef> for GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700211 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -0700212{
213 type Result = Self;
214
215 fn invoke(self, lifetime: LifetimeDef) -> Self {
216 self.with_lifetime(lifetime)
217 }
218}
219
220impl<F> Invoke<TyParam> for GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700221 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -0700222{
223 type Result = Self;
224
225 fn invoke(self, ty_param: TyParam) -> Self {
226 self.with_ty_param(ty_param)
227 }
228}
229
230impl<F> Invoke<WherePredicate> for GenericsBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700231 where F: Invoke<Generics>
David Tolnay55337722016-09-11 12:58:56 -0700232{
233 type Result = Self;
234
235 fn invoke(self, predicate: WherePredicate) -> Self {
236 self.with_predicate(predicate)
237 }
238}