blob: 04ff2a9fc2a95d4c9b00385988eb504803952c5c [file] [log] [blame]
David Tolnay55337722016-09-11 12:58:56 -07001use {
2 Generics,
3 Lifetime,
4 MutTy,
5 Mutability,
6 Path,
7 QSelf,
8 Ty,
9 TyParamBound,
10};
11use aster::ident::ToIdent;
12use aster::invoke::{Invoke, Identity};
13use aster::lifetime::IntoLifetime;
14use aster::path::PathBuilder;
15use aster::qpath::QPathBuilder;
16use aster::ty_param::TyParamBoundBuilder;
17
18//////////////////////////////////////////////////////////////////////////////
19
20pub struct TyBuilder<F=Identity> {
21 callback: F,
22}
23
24impl TyBuilder {
25 pub fn new() -> Self {
26 TyBuilder::with_callback(Identity)
27 }
28}
29
30impl<F> TyBuilder<F>
31 where F: Invoke<Ty>,
32{
33 pub fn with_callback(callback: F) -> Self {
34 TyBuilder {
35 callback: callback,
36 }
37 }
38
39 pub fn build(self, ty: Ty) -> F::Result {
40 self.callback.invoke(ty)
41 }
42
43 pub fn id<I>(self, id: I) -> F::Result
44 where I: ToIdent,
45 {
46 self.path().id(id).build()
47 }
48
49 pub fn build_path(self, path: Path) -> F::Result {
50 self.build(Ty::Path(None, path))
51 }
52
53 pub fn build_qpath(self, qself: QSelf, path: Path) -> F::Result {
54 self.build(Ty::Path(Some(qself), path))
55 }
56
57 pub fn path(self) -> PathBuilder<TyPathBuilder<F>> {
58 PathBuilder::with_callback(TyPathBuilder(self))
59 }
60
61 pub fn qpath(self) -> QPathBuilder<TyQPathBuilder<F>> {
62 QPathBuilder::with_callback(TyQPathBuilder(self))
63 }
64
65 pub fn isize(self) -> F::Result {
66 self.id("isize")
67 }
68
69 pub fn i8(self) -> F::Result {
70 self.id("i8")
71 }
72
73 pub fn i16(self) -> F::Result {
74 self.id("i16")
75 }
76
77 pub fn i32(self) -> F::Result {
78 self.id("i32")
79 }
80
81 pub fn i64(self) -> F::Result {
82 self.id("i64")
83 }
84
85 pub fn usize(self) -> F::Result {
86 self.id("usize")
87 }
88
89 pub fn u8(self) -> F::Result {
90 self.id("u8")
91 }
92
93 pub fn u16(self) -> F::Result {
94 self.id("u16")
95 }
96
97 pub fn u32(self) -> F::Result {
98 self.id("u32")
99 }
100
101 pub fn u64(self) -> F::Result {
102 self.id("u64")
103 }
104
105 pub fn f32(self) -> F::Result {
106 self.id("f32")
107 }
108
109 pub fn f64(self) -> F::Result {
110 self.id("f64")
111 }
112
113 pub fn bool(self) -> F::Result {
114 self.id("bool")
115 }
116
117 pub fn unit(self) -> F::Result {
118 self.tuple().build()
119 }
120
121 pub fn tuple(self) -> TyTupleBuilder<F> {
122 TyTupleBuilder {
123 builder: self,
124 tys: vec![],
125 }
126 }
127
128 pub fn build_slice(self, ty: Ty) -> F::Result {
129 self.build(Ty::Vec(Box::new(ty)))
130 }
131
132 pub fn slice(self) -> TyBuilder<TySliceBuilder<F>> {
133 TyBuilder::with_callback(TySliceBuilder(self))
134 }
135
136 pub fn ref_(self) -> TyRefBuilder<F> {
137 TyRefBuilder {
138 builder: self,
139 lifetime: None,
140 mutability: Mutability::Immutable,
141 }
142 }
143
144 pub fn never(self) -> F::Result {
145 self.build(Ty::Never)
146 }
147
148 pub fn infer(self) -> F::Result {
149 self.build(Ty::Infer)
150 }
151
152 pub fn option(self) -> TyBuilder<TyOptionBuilder<F>> {
153 TyBuilder::with_callback(TyOptionBuilder(self))
154 }
155
156 pub fn result(self) -> TyBuilder<TyResultOkBuilder<F>> {
157 TyBuilder::with_callback(TyResultOkBuilder(self))
158 }
159
160 pub fn phantom_data(self) -> TyBuilder<TyPhantomDataBuilder<F>> {
161 TyBuilder::with_callback(TyPhantomDataBuilder(self))
162 }
163
164 pub fn box_(self) -> TyBuilder<TyBoxBuilder<F>> {
165 TyBuilder::with_callback(TyBoxBuilder(self))
166 }
167
168 pub fn iterator(self) -> TyBuilder<TyIteratorBuilder<F>> {
169 TyBuilder::with_callback(TyIteratorBuilder(self))
170 }
171
172 pub fn object_sum(self) -> TyBuilder<TyObjectSumBuilder<F>> {
173 TyBuilder::with_callback(TyObjectSumBuilder {
174 builder: self,
175 })
176 }
177
178 pub fn impl_trait(self) -> TyImplTraitTyBuilder<F> {
179 TyImplTraitTyBuilder { builder: self, bounds: Vec::new() }
180 }
181}
182
183//////////////////////////////////////////////////////////////////////////////
184
185pub struct TyPathBuilder<F>(TyBuilder<F>);
186
187impl<F> Invoke<Path> for TyPathBuilder<F>
188 where F: Invoke<Ty>,
189{
190 type Result = F::Result;
191
192 fn invoke(self, path: Path) -> F::Result {
193 self.0.build_path(path)
194 }
195}
196
197//////////////////////////////////////////////////////////////////////////////
198
199pub struct TyQPathBuilder<F>(TyBuilder<F>);
200
201impl<F> Invoke<(QSelf, Path)> for TyQPathBuilder<F>
202 where F: Invoke<Ty>,
203{
204 type Result = F::Result;
205
206 fn invoke(self, (qself, path): (QSelf, Path)) -> F::Result {
207 self.0.build_qpath(qself, path)
208 }
209}
210
211//////////////////////////////////////////////////////////////////////////////
212
213pub struct TySliceBuilder<F>(TyBuilder<F>);
214
215impl<F> Invoke<Ty> for TySliceBuilder<F>
216 where F: Invoke<Ty>,
217{
218 type Result = F::Result;
219
220 fn invoke(self, ty: Ty) -> F::Result {
221 self.0.build_slice(ty)
222 }
223}
224
225//////////////////////////////////////////////////////////////////////////////
226
227pub struct TyRefBuilder<F> {
228 builder: TyBuilder<F>,
229 lifetime: Option<Lifetime>,
230 mutability: Mutability,
231}
232
233impl<F> TyRefBuilder<F>
234 where F: Invoke<Ty>,
235{
236 pub fn mut_(mut self) -> Self {
237 self.mutability = Mutability::Mutable;
238 self
239 }
240
241 pub fn lifetime<N>(mut self, name: N) -> Self
242 where N: ToIdent,
243 {
244 self.lifetime = Some(Lifetime {
245 ident: name.to_ident(),
246 });
247 self
248 }
249
250 pub fn build_ty(self, ty: Ty) -> F::Result {
251 let ty = MutTy {
252 ty: ty,
253 mutability: self.mutability,
254 };
255 self.builder.build(Ty::Rptr(self.lifetime, Box::new(ty)))
256 }
257
258 pub fn ty(self) -> TyBuilder<Self> {
259 TyBuilder::with_callback(self)
260 }
261}
262
263impl<F> Invoke<Ty> for TyRefBuilder<F>
264 where F: Invoke<Ty>,
265{
266 type Result = F::Result;
267
268 fn invoke(self, ty: Ty) -> F::Result {
269 self.build_ty(ty)
270 }
271}
272
273//////////////////////////////////////////////////////////////////////////////
274
275pub struct TyOptionBuilder<F>(TyBuilder<F>);
276
277impl<F> Invoke<Ty> for TyOptionBuilder<F>
278 where F: Invoke<Ty>,
279{
280 type Result = F::Result;
281
282 fn invoke(self, ty: Ty) -> F::Result {
283 let path = PathBuilder::new()
284 .global()
285 .id("std")
286 .id("option")
287 .segment("Option")
288 .with_ty(ty)
289 .build()
290 .build();
291
292 self.0.build_path(path)
293 }
294}
295
296//////////////////////////////////////////////////////////////////////////////
297
298pub struct TyResultOkBuilder<F>(TyBuilder<F>);
299
300impl<F> Invoke<Ty> for TyResultOkBuilder<F>
301 where F: Invoke<Ty>,
302{
303 type Result = TyBuilder<TyResultErrBuilder<F>>;
304
305 fn invoke(self, ty: Ty) -> TyBuilder<TyResultErrBuilder<F>> {
306 TyBuilder::with_callback(TyResultErrBuilder(self.0, ty))
307 }
308}
309
310pub struct TyResultErrBuilder<F>(TyBuilder<F>, Ty);
311
312impl<F> Invoke<Ty> for TyResultErrBuilder<F>
313 where F: Invoke<Ty>,
314{
315 type Result = F::Result;
316
317 fn invoke(self, ty: Ty) -> F::Result {
318 let path = PathBuilder::new()
319 .global()
320 .id("std")
321 .id("result")
322 .segment("Result")
323 .with_ty(self.1)
324 .with_ty(ty)
325 .build()
326 .build();
327
328 self.0.build_path(path)
329 }
330}
331
332//////////////////////////////////////////////////////////////////////////////
333
334pub struct TyPhantomDataBuilder<F>(TyBuilder<F>);
335
336impl<F> Invoke<Ty> for TyPhantomDataBuilder<F>
337 where F: Invoke<Ty>,
338{
339 type Result = F::Result;
340
341 fn invoke(self, ty: Ty) -> F::Result {
342 let path = PathBuilder::new()
343 .global()
344 .id("std")
345 .id("marker")
346 .segment("PhantomData")
347 .with_ty(ty)
348 .build()
349 .build();
350
351 self.0.build_path(path)
352 }
353}
354
355//////////////////////////////////////////////////////////////////////////////
356
357pub struct TyBoxBuilder<F>(TyBuilder<F>);
358
359impl<F> Invoke<Ty> for TyBoxBuilder<F>
360 where F: Invoke<Ty>,
361{
362 type Result = F::Result;
363
364 fn invoke(self, ty: Ty) -> F::Result {
365 let path = PathBuilder::new()
366 .global()
367 .id("std")
368 .id("boxed")
369 .segment("Box")
370 .with_ty(ty)
371 .build()
372 .build();
373
374 self.0.build_path(path)
375 }
376}
377
378//////////////////////////////////////////////////////////////////////////////
379
380pub struct TyIteratorBuilder<F>(TyBuilder<F>);
381
382impl<F> Invoke<Ty> for TyIteratorBuilder<F>
383 where F: Invoke<Ty>,
384{
385 type Result = F::Result;
386
387 fn invoke(self, ty: Ty) -> F::Result {
388 let path = PathBuilder::new()
389 .global()
390 .id("std")
391 .id("iter")
392 .segment("Iterator")
393 .binding("Item").build(ty.clone())
394 .build()
395 .build();
396
397 self.0.build_path(path)
398 }
399}
400
401//////////////////////////////////////////////////////////////////////////////
402
403pub struct TyObjectSumBuilder<F> {
404 builder: TyBuilder<F>,
405}
406
407impl<F> Invoke<Ty> for TyObjectSumBuilder<F>
408 where F: Invoke<Ty>,
409{
410 type Result = TyObjectSumTyBuilder<F>;
411
412 fn invoke(self, ty: Ty) -> Self::Result {
413 TyObjectSumTyBuilder {
414 builder: self.builder,
415 ty: ty,
416 bounds: Vec::new(),
417 }
418 }
419}
420
421pub struct TyObjectSumTyBuilder<F> {
422 builder: TyBuilder<F>,
423 ty: Ty,
424 bounds: Vec<TyParamBound>,
425}
426
427impl<F> TyObjectSumTyBuilder<F>
428 where F: Invoke<Ty>,
429{
430 pub fn with_bounds<I>(mut self, iter: I) -> Self
431 where I: Iterator<Item=TyParamBound>,
432 {
433 self.bounds.extend(iter);
434 self
435 }
436
437 pub fn with_bound(mut self, bound: TyParamBound) -> Self {
438 self.bounds.push(bound);
439 self
440 }
441
442 pub fn bound(self) -> TyParamBoundBuilder<Self> {
443 TyParamBoundBuilder::with_callback(self)
444 }
445
446 pub fn with_generics(self, generics: Generics) -> Self {
447 self.with_lifetimes(
448 generics.lifetimes.into_iter()
449 .map(|def| def.lifetime)
450 )
451 }
452
453 pub fn with_lifetimes<I, L>(mut self, lifetimes: I) -> Self
454 where I: Iterator<Item=L>,
455 L: IntoLifetime,
456 {
457 for lifetime in lifetimes {
458 self = self.lifetime(lifetime);
459 }
460
461 self
462 }
463
464 pub fn lifetime<L>(self, lifetime: L) -> Self
465 where L: IntoLifetime,
466 {
467 self.bound().lifetime(lifetime)
468 }
469
470 pub fn build(self) -> F::Result {
471 let bounds = self.bounds;
472 self.builder.build(Ty::ObjectSum(Box::new(self.ty), bounds))
473 }
474}
475
476impl<F> Invoke<TyParamBound> for TyObjectSumTyBuilder<F>
477 where F: Invoke<Ty>,
478{
479 type Result = Self;
480
481 fn invoke(self, bound: TyParamBound) -> Self {
482 self.with_bound(bound)
483 }
484}
485
486//////////////////////////////////////////////////////////////////////////////
487
488pub struct TyImplTraitTyBuilder<F> {
489 builder: TyBuilder<F>,
490 bounds: Vec<TyParamBound>,
491}
492
493impl<F> TyImplTraitTyBuilder<F>
494 where F: Invoke<Ty>,
495{
496 pub fn with_bounds<I>(mut self, iter: I) -> Self
497 where I: Iterator<Item=TyParamBound>,
498 {
499 self.bounds.extend(iter);
500 self
501 }
502
503 pub fn with_bound(mut self, bound: TyParamBound) -> Self {
504 self.bounds.push(bound);
505 self
506 }
507
508 pub fn bound(self) -> TyParamBoundBuilder<Self> {
509 TyParamBoundBuilder::with_callback(self)
510 }
511
512 pub fn with_generics(self, generics: Generics) -> Self {
513 self.with_lifetimes(
514 generics.lifetimes.into_iter()
515 .map(|def| def.lifetime)
516 )
517 }
518
519 pub fn with_lifetimes<I, L>(mut self, lifetimes: I) -> Self
520 where I: Iterator<Item=L>,
521 L: IntoLifetime,
522 {
523 for lifetime in lifetimes {
524 self = self.lifetime(lifetime);
525 }
526
527 self
528 }
529
530 pub fn lifetime<L>(self, lifetime: L) -> Self
531 where L: IntoLifetime,
532 {
533 self.bound().lifetime(lifetime)
534 }
535
536 pub fn build(self) -> F::Result {
537 let bounds = self.bounds;
538 self.builder.build(Ty::ImplTrait(bounds))
539 }
540}
541
542impl<F> Invoke<TyParamBound> for TyImplTraitTyBuilder<F>
543 where F: Invoke<Ty>,
544{
545 type Result = Self;
546
547 fn invoke(self, bound: TyParamBound) -> Self {
548 self.with_bound(bound)
549 }
550}
551
552//////////////////////////////////////////////////////////////////////////////
553
554pub struct TyTupleBuilder<F> {
555 builder: TyBuilder<F>,
556 tys: Vec<Ty>,
557}
558
559impl<F> TyTupleBuilder<F>
560 where F: Invoke<Ty>,
561{
562 pub fn with_tys<I>(mut self, iter: I) -> Self
563 where I: IntoIterator<Item=Ty>,
564 {
565 self.tys.extend(iter);
566 self
567 }
568
569 pub fn with_ty(mut self, ty: Ty) -> Self {
570 self.tys.push(ty);
571 self
572 }
573
574 pub fn ty(self) -> TyBuilder<Self> {
575 TyBuilder::with_callback(self)
576 }
577
578 pub fn build(self) -> F::Result {
579 self.builder.build(Ty::Tup(self.tys))
580 }
581}
582
583impl<F> Invoke<Ty> for TyTupleBuilder<F>
584 where F: Invoke<Ty>,
585{
586 type Result = Self;
587
588 fn invoke(self, ty: Ty) -> Self {
589 self.with_ty(ty)
590 }
591}