blob: 6ecde8609b6207685b446e2a3a4802984bba4e03 [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.
David Tolnay58f6f672016-10-19 08:44:25 -070068 // Clippy false positive
69 // https://github.com/Manishearth/rust-clippy/issues/1285
70 #[cfg_attr(feature = "clippy", allow(wrong_self_convention))]
David Tolnay55337722016-09-11 12:58:56 -070071 pub fn as_(self) -> PathBuilder<Self> {
72 PathBuilder::with_callback(self)
73 }
74
75 pub fn id<T>(self, id: T) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -070076 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070077 {
78 let path = Path {
79 global: false,
80 segments: vec![],
81 };
82 self.as_().build(path).id(id)
83 }
84
85 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
David Tolnaydaaf7742016-10-03 11:11:43 -070086 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070087 {
88 let path = Path {
89 global: false,
90 segments: vec![],
91 };
92 self.as_().build(path).segment(id)
93 }
94}
95
96impl<F> Invoke<Path> for QPathTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070097 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070098{
99 type Result = QPathQSelfBuilder<F>;
100
101 fn invoke(self, path: Path) -> QPathQSelfBuilder<F> {
102 QPathQSelfBuilder {
103 builder: self.builder,
104 qself: QSelf {
105 ty: Box::new(self.ty),
106 position: path.segments.len(),
107 },
108 path: path,
109 }
110 }
111}
112
David Tolnaydaaf7742016-10-03 11:11:43 -0700113// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700114
115pub struct QPathQSelfBuilder<F> {
116 builder: QPathBuilder<F>,
117 qself: QSelf,
118 path: Path,
119}
120
121impl<F> QPathQSelfBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700122 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -0700123{
124 pub fn id<T>(self, id: T) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -0700125 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700126 {
127 self.segment(id).build()
128 }
129
130 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
David Tolnaydaaf7742016-10-03 11:11:43 -0700131 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700132 {
133 PathSegmentBuilder::with_callback(id, self)
134 }
135}
136
137impl<F> Invoke<PathSegment> for QPathQSelfBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700138 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -0700139{
140 type Result = F::Result;
141
142 fn invoke(mut self, segment: PathSegment) -> F::Result {
143 self.path.segments.push(segment);
144 self.builder.build(self.qself, self.path)
145 }
146}