blob: 71f68b147a8988e0761fb76bbf6e7c29eec4ef44 [file] [log] [blame]
David Tolnaydaaf7742016-10-03 11:11:43 -07001use {Path, PathSegment, QSelf, Ty};
David Tolnay55337722016-09-11 12:58:56 -07002use aster::ident::ToIdent;
3use aster::invoke::{Invoke, Identity};
4use aster::path::{PathBuilder, PathSegmentBuilder};
5use aster::ty::TyBuilder;
6
David Tolnaydaaf7742016-10-03 11:11:43 -07007// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -07008
David Tolnaydaaf7742016-10-03 11:11:43 -07009pub struct QPathBuilder<F = Identity> {
David Tolnay55337722016-09-11 12:58:56 -070010 callback: F,
11}
12
13impl QPathBuilder {
14 pub fn new() -> Self {
15 QPathBuilder::with_callback(Identity)
16 }
17}
18
19impl<F> QPathBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070020 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070021{
22 /// Construct a `QPathBuilder` that will call the `callback` with a constructed `QSelf`
23 /// and `Path`.
24 pub fn with_callback(callback: F) -> Self {
David Tolnaydaaf7742016-10-03 11:11:43 -070025 QPathBuilder { callback: callback }
David Tolnay55337722016-09-11 12:58:56 -070026 }
27
28 /// Build a qualified path first by starting with a type builder.
29 pub fn with_ty(self, ty: Ty) -> QPathTyBuilder<F> {
30 QPathTyBuilder {
31 builder: self,
32 ty: ty,
33 }
34 }
35
36 /// Build a qualified path first by starting with a type builder.
37 pub fn ty(self) -> TyBuilder<Self> {
38 TyBuilder::with_callback(self)
39 }
40
41 /// Build a qualified path with a concrete type and path.
42 pub fn build(self, qself: QSelf, path: Path) -> F::Result {
43 self.callback.invoke((qself, path))
44 }
45}
46
47impl<F> Invoke<Ty> for QPathBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070048 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070049{
50 type Result = QPathTyBuilder<F>;
51
52 fn invoke(self, ty: Ty) -> QPathTyBuilder<F> {
53 self.with_ty(ty)
54 }
55}
56
David Tolnaydaaf7742016-10-03 11:11:43 -070057// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -070058
59pub struct QPathTyBuilder<F> {
60 builder: QPathBuilder<F>,
61 ty: Ty,
62}
63
64impl<F> QPathTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070065 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070066{
67 /// Build a qualified path with a path builder.
68 pub fn as_(self) -> PathBuilder<Self> {
69 PathBuilder::with_callback(self)
70 }
71
72 pub fn id<T>(self, id: T) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -070073 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070074 {
75 let path = Path {
76 global: false,
77 segments: vec![],
78 };
79 self.as_().build(path).id(id)
80 }
81
82 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
David Tolnaydaaf7742016-10-03 11:11:43 -070083 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070084 {
85 let path = Path {
86 global: false,
87 segments: vec![],
88 };
89 self.as_().build(path).segment(id)
90 }
91}
92
93impl<F> Invoke<Path> for QPathTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070094 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070095{
96 type Result = QPathQSelfBuilder<F>;
97
98 fn invoke(self, path: Path) -> QPathQSelfBuilder<F> {
99 QPathQSelfBuilder {
100 builder: self.builder,
101 qself: QSelf {
102 ty: Box::new(self.ty),
103 position: path.segments.len(),
104 },
105 path: path,
106 }
107 }
108}
109
David Tolnaydaaf7742016-10-03 11:11:43 -0700110// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700111
112pub struct QPathQSelfBuilder<F> {
113 builder: QPathBuilder<F>,
114 qself: QSelf,
115 path: Path,
116}
117
118impl<F> QPathQSelfBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700119 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -0700120{
121 pub fn id<T>(self, id: T) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -0700122 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700123 {
124 self.segment(id).build()
125 }
126
127 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
David Tolnaydaaf7742016-10-03 11:11:43 -0700128 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700129 {
130 PathSegmentBuilder::with_callback(id, self)
131 }
132}
133
134impl<F> Invoke<PathSegment> for QPathQSelfBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700135 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -0700136{
137 type Result = F::Result;
138
139 fn invoke(mut self, segment: PathSegment) -> F::Result {
140 self.path.segments.push(segment);
141 self.builder.build(self.qself, self.path)
142 }
143}