blob: ab2516e8f4fc53d82840a1fef220d65a6aa2c68c [file] [log] [blame]
David Tolnay55337722016-09-11 12:58:56 -07001use {
2 Path,
3 PathSegment,
4 QSelf,
5 Ty,
6};
7use aster::ident::ToIdent;
8use aster::invoke::{Invoke, Identity};
9use aster::path::{PathBuilder, PathSegmentBuilder};
10use aster::ty::TyBuilder;
11
12//////////////////////////////////////////////////////////////////////////////
13
14pub struct QPathBuilder<F=Identity> {
15 callback: F,
16}
17
18impl QPathBuilder {
19 pub fn new() -> Self {
20 QPathBuilder::with_callback(Identity)
21 }
22}
23
24impl<F> QPathBuilder<F>
25 where F: Invoke<(QSelf, Path)>,
26{
27 /// Construct a `QPathBuilder` that will call the `callback` with a constructed `QSelf`
28 /// and `Path`.
29 pub fn with_callback(callback: F) -> Self {
30 QPathBuilder {
31 callback: callback,
32 }
33 }
34
35 /// Build a qualified path first by starting with a type builder.
36 pub fn with_ty(self, ty: Ty) -> QPathTyBuilder<F> {
37 QPathTyBuilder {
38 builder: self,
39 ty: ty,
40 }
41 }
42
43 /// Build a qualified path first by starting with a type builder.
44 pub fn ty(self) -> TyBuilder<Self> {
45 TyBuilder::with_callback(self)
46 }
47
48 /// Build a qualified path with a concrete type and path.
49 pub fn build(self, qself: QSelf, path: Path) -> F::Result {
50 self.callback.invoke((qself, path))
51 }
52}
53
54impl<F> Invoke<Ty> for QPathBuilder<F>
55 where F: Invoke<(QSelf, Path)>,
56{
57 type Result = QPathTyBuilder<F>;
58
59 fn invoke(self, ty: Ty) -> QPathTyBuilder<F> {
60 self.with_ty(ty)
61 }
62}
63
64//////////////////////////////////////////////////////////////////////////////
65
66pub struct QPathTyBuilder<F> {
67 builder: QPathBuilder<F>,
68 ty: Ty,
69}
70
71impl<F> QPathTyBuilder<F>
72 where F: Invoke<(QSelf, Path)>,
73{
74 /// Build a qualified path with a path builder.
75 pub fn as_(self) -> PathBuilder<Self> {
76 PathBuilder::with_callback(self)
77 }
78
79 pub fn id<T>(self, id: T) -> F::Result
80 where T: ToIdent,
81 {
82 let path = Path {
83 global: false,
84 segments: vec![],
85 };
86 self.as_().build(path).id(id)
87 }
88
89 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
90 where T: ToIdent,
91 {
92 let path = Path {
93 global: false,
94 segments: vec![],
95 };
96 self.as_().build(path).segment(id)
97 }
98}
99
100impl<F> Invoke<Path> for QPathTyBuilder<F>
101 where F: Invoke<(QSelf, Path)>,
102{
103 type Result = QPathQSelfBuilder<F>;
104
105 fn invoke(self, path: Path) -> QPathQSelfBuilder<F> {
106 QPathQSelfBuilder {
107 builder: self.builder,
108 qself: QSelf {
109 ty: Box::new(self.ty),
110 position: path.segments.len(),
111 },
112 path: path,
113 }
114 }
115}
116
117//////////////////////////////////////////////////////////////////////////////
118
119pub struct QPathQSelfBuilder<F> {
120 builder: QPathBuilder<F>,
121 qself: QSelf,
122 path: Path,
123}
124
125impl<F> QPathQSelfBuilder<F>
126 where F: Invoke<(QSelf, Path)>,
127{
128 pub fn id<T>(self, id: T) -> F::Result
129 where T: ToIdent,
130 {
131 self.segment(id).build()
132 }
133
134 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
135 where T: ToIdent,
136 {
137 PathSegmentBuilder::with_callback(id, self)
138 }
139}
140
141impl<F> Invoke<PathSegment> for QPathQSelfBuilder<F>
142 where F: Invoke<(QSelf, Path)>,
143{
144 type Result = F::Result;
145
146 fn invoke(mut self, segment: PathSegment) -> F::Result {
147 self.path.segments.push(segment);
148 self.builder.build(self.qself, self.path)
149 }
150}