blob: 96b6554d20c12d8e3e80027e48e512238221c299 [file] [log] [blame]
David Tolnaydaaf7742016-10-03 11:11:43 -07001use {Generics, Lifetime, MutTy, Mutability, Path, QSelf, Ty, TyParamBound};
David Tolnay55337722016-09-11 12:58:56 -07002use aster::ident::ToIdent;
3use aster::invoke::{Invoke, Identity};
4use aster::lifetime::IntoLifetime;
5use aster::path::PathBuilder;
6use aster::qpath::QPathBuilder;
7use aster::ty_param::TyParamBoundBuilder;
8
David Tolnaydaaf7742016-10-03 11:11:43 -07009// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -070010
David Tolnaydaaf7742016-10-03 11:11:43 -070011pub struct TyBuilder<F = Identity> {
David Tolnay55337722016-09-11 12:58:56 -070012 callback: F,
13}
14
15impl TyBuilder {
16 pub fn new() -> Self {
17 TyBuilder::with_callback(Identity)
18 }
19}
20
21impl<F> TyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070022 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -070023{
24 pub fn with_callback(callback: F) -> Self {
David Tolnaydaaf7742016-10-03 11:11:43 -070025 TyBuilder { callback: callback }
David Tolnay55337722016-09-11 12:58:56 -070026 }
27
28 pub fn build(self, ty: Ty) -> F::Result {
29 self.callback.invoke(ty)
30 }
31
32 pub fn id<I>(self, id: I) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -070033 where I: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070034 {
35 self.path().id(id).build()
36 }
37
38 pub fn build_path(self, path: Path) -> F::Result {
39 self.build(Ty::Path(None, path))
40 }
41
42 pub fn build_qpath(self, qself: QSelf, path: Path) -> F::Result {
43 self.build(Ty::Path(Some(qself), path))
44 }
45
46 pub fn path(self) -> PathBuilder<TyPathBuilder<F>> {
47 PathBuilder::with_callback(TyPathBuilder(self))
48 }
49
50 pub fn qpath(self) -> QPathBuilder<TyQPathBuilder<F>> {
51 QPathBuilder::with_callback(TyQPathBuilder(self))
52 }
53
54 pub fn isize(self) -> F::Result {
55 self.id("isize")
56 }
57
58 pub fn i8(self) -> F::Result {
59 self.id("i8")
60 }
61
62 pub fn i16(self) -> F::Result {
63 self.id("i16")
64 }
65
66 pub fn i32(self) -> F::Result {
67 self.id("i32")
68 }
69
70 pub fn i64(self) -> F::Result {
71 self.id("i64")
72 }
73
74 pub fn usize(self) -> F::Result {
75 self.id("usize")
76 }
77
78 pub fn u8(self) -> F::Result {
79 self.id("u8")
80 }
81
82 pub fn u16(self) -> F::Result {
83 self.id("u16")
84 }
85
86 pub fn u32(self) -> F::Result {
87 self.id("u32")
88 }
89
90 pub fn u64(self) -> F::Result {
91 self.id("u64")
92 }
93
94 pub fn f32(self) -> F::Result {
95 self.id("f32")
96 }
97
98 pub fn f64(self) -> F::Result {
99 self.id("f64")
100 }
101
102 pub fn bool(self) -> F::Result {
103 self.id("bool")
104 }
105
106 pub fn unit(self) -> F::Result {
107 self.tuple().build()
108 }
109
110 pub fn tuple(self) -> TyTupleBuilder<F> {
111 TyTupleBuilder {
112 builder: self,
113 tys: vec![],
114 }
115 }
116
117 pub fn build_slice(self, ty: Ty) -> F::Result {
David Tolnay429168f2016-10-05 23:41:04 -0700118 self.build(Ty::Slice(Box::new(ty)))
David Tolnay55337722016-09-11 12:58:56 -0700119 }
120
121 pub fn slice(self) -> TyBuilder<TySliceBuilder<F>> {
122 TyBuilder::with_callback(TySliceBuilder(self))
123 }
124
125 pub fn ref_(self) -> TyRefBuilder<F> {
126 TyRefBuilder {
127 builder: self,
128 lifetime: None,
129 mutability: Mutability::Immutable,
130 }
131 }
132
133 pub fn never(self) -> F::Result {
134 self.build(Ty::Never)
135 }
136
137 pub fn infer(self) -> F::Result {
138 self.build(Ty::Infer)
139 }
140
141 pub fn option(self) -> TyBuilder<TyOptionBuilder<F>> {
142 TyBuilder::with_callback(TyOptionBuilder(self))
143 }
144
145 pub fn result(self) -> TyBuilder<TyResultOkBuilder<F>> {
146 TyBuilder::with_callback(TyResultOkBuilder(self))
147 }
148
149 pub fn phantom_data(self) -> TyBuilder<TyPhantomDataBuilder<F>> {
150 TyBuilder::with_callback(TyPhantomDataBuilder(self))
151 }
152
153 pub fn box_(self) -> TyBuilder<TyBoxBuilder<F>> {
154 TyBuilder::with_callback(TyBoxBuilder(self))
155 }
156
157 pub fn iterator(self) -> TyBuilder<TyIteratorBuilder<F>> {
158 TyBuilder::with_callback(TyIteratorBuilder(self))
159 }
160
161 pub fn object_sum(self) -> TyBuilder<TyObjectSumBuilder<F>> {
David Tolnaydaaf7742016-10-03 11:11:43 -0700162 TyBuilder::with_callback(TyObjectSumBuilder { builder: self })
David Tolnay55337722016-09-11 12:58:56 -0700163 }
164
165 pub fn impl_trait(self) -> TyImplTraitTyBuilder<F> {
David Tolnaydaaf7742016-10-03 11:11:43 -0700166 TyImplTraitTyBuilder {
167 builder: self,
168 bounds: Vec::new(),
169 }
David Tolnay55337722016-09-11 12:58:56 -0700170 }
171}
172
David Tolnaydaaf7742016-10-03 11:11:43 -0700173// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700174
175pub struct TyPathBuilder<F>(TyBuilder<F>);
176
177impl<F> Invoke<Path> for TyPathBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700178 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700179{
180 type Result = F::Result;
181
182 fn invoke(self, path: Path) -> F::Result {
183 self.0.build_path(path)
184 }
185}
186
David Tolnaydaaf7742016-10-03 11:11:43 -0700187// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700188
189pub struct TyQPathBuilder<F>(TyBuilder<F>);
190
191impl<F> Invoke<(QSelf, Path)> for TyQPathBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700192 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700193{
194 type Result = F::Result;
195
196 fn invoke(self, (qself, path): (QSelf, Path)) -> F::Result {
197 self.0.build_qpath(qself, path)
198 }
199}
200
David Tolnaydaaf7742016-10-03 11:11:43 -0700201// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700202
203pub struct TySliceBuilder<F>(TyBuilder<F>);
204
205impl<F> Invoke<Ty> for TySliceBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700206 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700207{
208 type Result = F::Result;
209
210 fn invoke(self, ty: Ty) -> F::Result {
211 self.0.build_slice(ty)
212 }
213}
214
David Tolnaydaaf7742016-10-03 11:11:43 -0700215// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700216
217pub struct TyRefBuilder<F> {
218 builder: TyBuilder<F>,
219 lifetime: Option<Lifetime>,
220 mutability: Mutability,
221}
222
223impl<F> TyRefBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700224 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700225{
226 pub fn mut_(mut self) -> Self {
227 self.mutability = Mutability::Mutable;
228 self
229 }
230
231 pub fn lifetime<N>(mut self, name: N) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700232 where N: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700233 {
David Tolnaydaaf7742016-10-03 11:11:43 -0700234 self.lifetime = Some(Lifetime { ident: name.to_ident() });
David Tolnay55337722016-09-11 12:58:56 -0700235 self
236 }
237
238 pub fn build_ty(self, ty: Ty) -> F::Result {
239 let ty = MutTy {
240 ty: ty,
241 mutability: self.mutability,
242 };
243 self.builder.build(Ty::Rptr(self.lifetime, Box::new(ty)))
244 }
245
246 pub fn ty(self) -> TyBuilder<Self> {
247 TyBuilder::with_callback(self)
248 }
249}
250
251impl<F> Invoke<Ty> for TyRefBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700252 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700253{
254 type Result = F::Result;
255
256 fn invoke(self, ty: Ty) -> F::Result {
257 self.build_ty(ty)
258 }
259}
260
David Tolnaydaaf7742016-10-03 11:11:43 -0700261// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700262
263pub struct TyOptionBuilder<F>(TyBuilder<F>);
264
265impl<F> Invoke<Ty> for TyOptionBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700266 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700267{
268 type Result = F::Result;
269
270 fn invoke(self, ty: Ty) -> F::Result {
271 let path = PathBuilder::new()
272 .global()
273 .id("std")
274 .id("option")
275 .segment("Option")
David Tolnaydaaf7742016-10-03 11:11:43 -0700276 .with_ty(ty)
277 .build()
David Tolnay55337722016-09-11 12:58:56 -0700278 .build();
279
280 self.0.build_path(path)
281 }
282}
283
David Tolnaydaaf7742016-10-03 11:11:43 -0700284// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700285
286pub struct TyResultOkBuilder<F>(TyBuilder<F>);
287
288impl<F> Invoke<Ty> for TyResultOkBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700289 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700290{
291 type Result = TyBuilder<TyResultErrBuilder<F>>;
292
293 fn invoke(self, ty: Ty) -> TyBuilder<TyResultErrBuilder<F>> {
294 TyBuilder::with_callback(TyResultErrBuilder(self.0, ty))
295 }
296}
297
298pub struct TyResultErrBuilder<F>(TyBuilder<F>, Ty);
299
300impl<F> Invoke<Ty> for TyResultErrBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700301 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700302{
303 type Result = F::Result;
304
305 fn invoke(self, ty: Ty) -> F::Result {
306 let path = PathBuilder::new()
307 .global()
308 .id("std")
309 .id("result")
310 .segment("Result")
David Tolnaydaaf7742016-10-03 11:11:43 -0700311 .with_ty(self.1)
312 .with_ty(ty)
313 .build()
David Tolnay55337722016-09-11 12:58:56 -0700314 .build();
315
316 self.0.build_path(path)
317 }
318}
319
David Tolnaydaaf7742016-10-03 11:11:43 -0700320// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700321
322pub struct TyPhantomDataBuilder<F>(TyBuilder<F>);
323
324impl<F> Invoke<Ty> for TyPhantomDataBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700325 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700326{
327 type Result = F::Result;
328
329 fn invoke(self, ty: Ty) -> F::Result {
330 let path = PathBuilder::new()
331 .global()
332 .id("std")
333 .id("marker")
334 .segment("PhantomData")
David Tolnaydaaf7742016-10-03 11:11:43 -0700335 .with_ty(ty)
336 .build()
David Tolnay55337722016-09-11 12:58:56 -0700337 .build();
338
339 self.0.build_path(path)
340 }
341}
342
David Tolnaydaaf7742016-10-03 11:11:43 -0700343// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700344
345pub struct TyBoxBuilder<F>(TyBuilder<F>);
346
347impl<F> Invoke<Ty> for TyBoxBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700348 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700349{
350 type Result = F::Result;
351
352 fn invoke(self, ty: Ty) -> F::Result {
353 let path = PathBuilder::new()
354 .global()
355 .id("std")
356 .id("boxed")
357 .segment("Box")
David Tolnaydaaf7742016-10-03 11:11:43 -0700358 .with_ty(ty)
359 .build()
David Tolnay55337722016-09-11 12:58:56 -0700360 .build();
361
362 self.0.build_path(path)
363 }
364}
365
David Tolnaydaaf7742016-10-03 11:11:43 -0700366// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700367
368pub struct TyIteratorBuilder<F>(TyBuilder<F>);
369
370impl<F> Invoke<Ty> for TyIteratorBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700371 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700372{
373 type Result = F::Result;
374
375 fn invoke(self, ty: Ty) -> F::Result {
376 let path = PathBuilder::new()
377 .global()
378 .id("std")
379 .id("iter")
380 .segment("Iterator")
David Tolnaydaaf7742016-10-03 11:11:43 -0700381 .binding("Item")
382 .build(ty.clone())
383 .build()
David Tolnay55337722016-09-11 12:58:56 -0700384 .build();
385
386 self.0.build_path(path)
387 }
388}
389
David Tolnaydaaf7742016-10-03 11:11:43 -0700390// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700391
392pub struct TyObjectSumBuilder<F> {
393 builder: TyBuilder<F>,
394}
395
396impl<F> Invoke<Ty> for TyObjectSumBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700397 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700398{
399 type Result = TyObjectSumTyBuilder<F>;
400
401 fn invoke(self, ty: Ty) -> Self::Result {
402 TyObjectSumTyBuilder {
403 builder: self.builder,
404 ty: ty,
405 bounds: Vec::new(),
406 }
407 }
408}
409
410pub struct TyObjectSumTyBuilder<F> {
411 builder: TyBuilder<F>,
412 ty: Ty,
413 bounds: Vec<TyParamBound>,
414}
415
416impl<F> TyObjectSumTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700417 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700418{
419 pub fn with_bounds<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700420 where I: Iterator<Item = TyParamBound>
David Tolnay55337722016-09-11 12:58:56 -0700421 {
422 self.bounds.extend(iter);
423 self
424 }
425
426 pub fn with_bound(mut self, bound: TyParamBound) -> Self {
427 self.bounds.push(bound);
428 self
429 }
430
431 pub fn bound(self) -> TyParamBoundBuilder<Self> {
432 TyParamBoundBuilder::with_callback(self)
433 }
434
435 pub fn with_generics(self, generics: Generics) -> Self {
David Tolnaydaaf7742016-10-03 11:11:43 -0700436 self.with_lifetimes(generics.lifetimes
437 .into_iter()
438 .map(|def| def.lifetime))
David Tolnay55337722016-09-11 12:58:56 -0700439 }
440
441 pub fn with_lifetimes<I, L>(mut self, lifetimes: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700442 where I: Iterator<Item = L>,
443 L: IntoLifetime
David Tolnay55337722016-09-11 12:58:56 -0700444 {
445 for lifetime in lifetimes {
446 self = self.lifetime(lifetime);
447 }
448
449 self
450 }
451
452 pub fn lifetime<L>(self, lifetime: L) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700453 where L: IntoLifetime
David Tolnay55337722016-09-11 12:58:56 -0700454 {
455 self.bound().lifetime(lifetime)
456 }
457
458 pub fn build(self) -> F::Result {
459 let bounds = self.bounds;
460 self.builder.build(Ty::ObjectSum(Box::new(self.ty), bounds))
461 }
462}
463
464impl<F> Invoke<TyParamBound> for TyObjectSumTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700465 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700466{
467 type Result = Self;
468
469 fn invoke(self, bound: TyParamBound) -> Self {
470 self.with_bound(bound)
471 }
472}
473
David Tolnaydaaf7742016-10-03 11:11:43 -0700474// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700475
476pub struct TyImplTraitTyBuilder<F> {
477 builder: TyBuilder<F>,
478 bounds: Vec<TyParamBound>,
479}
480
481impl<F> TyImplTraitTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700482 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700483{
484 pub fn with_bounds<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700485 where I: Iterator<Item = TyParamBound>
David Tolnay55337722016-09-11 12:58:56 -0700486 {
487 self.bounds.extend(iter);
488 self
489 }
490
491 pub fn with_bound(mut self, bound: TyParamBound) -> Self {
492 self.bounds.push(bound);
493 self
494 }
495
496 pub fn bound(self) -> TyParamBoundBuilder<Self> {
497 TyParamBoundBuilder::with_callback(self)
498 }
499
500 pub fn with_generics(self, generics: Generics) -> Self {
David Tolnaydaaf7742016-10-03 11:11:43 -0700501 self.with_lifetimes(generics.lifetimes
502 .into_iter()
503 .map(|def| def.lifetime))
David Tolnay55337722016-09-11 12:58:56 -0700504 }
505
506 pub fn with_lifetimes<I, L>(mut self, lifetimes: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700507 where I: Iterator<Item = L>,
508 L: IntoLifetime
David Tolnay55337722016-09-11 12:58:56 -0700509 {
510 for lifetime in lifetimes {
511 self = self.lifetime(lifetime);
512 }
513
514 self
515 }
516
517 pub fn lifetime<L>(self, lifetime: L) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700518 where L: IntoLifetime
David Tolnay55337722016-09-11 12:58:56 -0700519 {
520 self.bound().lifetime(lifetime)
521 }
522
523 pub fn build(self) -> F::Result {
524 let bounds = self.bounds;
525 self.builder.build(Ty::ImplTrait(bounds))
526 }
527}
528
529impl<F> Invoke<TyParamBound> for TyImplTraitTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700530 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700531{
532 type Result = Self;
533
534 fn invoke(self, bound: TyParamBound) -> Self {
535 self.with_bound(bound)
536 }
537}
538
David Tolnaydaaf7742016-10-03 11:11:43 -0700539// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700540
541pub struct TyTupleBuilder<F> {
542 builder: TyBuilder<F>,
543 tys: Vec<Ty>,
544}
545
546impl<F> TyTupleBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700547 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700548{
549 pub fn with_tys<I>(mut self, iter: I) -> Self
David Tolnaydaaf7742016-10-03 11:11:43 -0700550 where I: IntoIterator<Item = Ty>
David Tolnay55337722016-09-11 12:58:56 -0700551 {
552 self.tys.extend(iter);
553 self
554 }
555
556 pub fn with_ty(mut self, ty: Ty) -> Self {
557 self.tys.push(ty);
558 self
559 }
560
561 pub fn ty(self) -> TyBuilder<Self> {
562 TyBuilder::with_callback(self)
563 }
564
565 pub fn build(self) -> F::Result {
566 self.builder.build(Ty::Tup(self.tys))
567 }
568}
569
570impl<F> Invoke<Ty> for TyTupleBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700571 where F: Invoke<Ty>
David Tolnay55337722016-09-11 12:58:56 -0700572{
573 type Result = Self;
574
575 fn invoke(self, ty: Ty) -> Self {
576 self.with_ty(ty)
577 }
578}