blob: ea36837a11f49804074dd6021e91e12bb3a8b09d [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;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07006use delimited::Delimited;
David Tolnay55337722016-09-11 12:58:56 -07007
David Tolnaydaaf7742016-10-03 11:11:43 -07008// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -07009
David Tolnaydaaf7742016-10-03 11:11:43 -070010pub struct QPathBuilder<F = Identity> {
David Tolnay55337722016-09-11 12:58:56 -070011 callback: F,
12}
13
14impl QPathBuilder {
15 pub fn new() -> Self {
16 QPathBuilder::with_callback(Identity)
17 }
18}
19
20impl<F> QPathBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070021 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070022{
23 /// Construct a `QPathBuilder` that will call the `callback` with a constructed `QSelf`
24 /// and `Path`.
25 pub fn with_callback(callback: F) -> Self {
David Tolnaydaaf7742016-10-03 11:11:43 -070026 QPathBuilder { callback: callback }
David Tolnay55337722016-09-11 12:58:56 -070027 }
28
29 /// Build a qualified path first by starting with a type builder.
30 pub fn with_ty(self, ty: Ty) -> QPathTyBuilder<F> {
31 QPathTyBuilder {
32 builder: self,
33 ty: ty,
34 }
35 }
36
37 /// Build a qualified path first by starting with a type builder.
38 pub fn ty(self) -> TyBuilder<Self> {
39 TyBuilder::with_callback(self)
40 }
41
42 /// Build a qualified path with a concrete type and path.
43 pub fn build(self, qself: QSelf, path: Path) -> F::Result {
44 self.callback.invoke((qself, path))
45 }
46}
47
48impl<F> Invoke<Ty> for QPathBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070049 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070050{
51 type Result = QPathTyBuilder<F>;
52
53 fn invoke(self, ty: Ty) -> QPathTyBuilder<F> {
54 self.with_ty(ty)
55 }
56}
57
David Tolnaydaaf7742016-10-03 11:11:43 -070058// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -070059
60pub struct QPathTyBuilder<F> {
61 builder: QPathBuilder<F>,
62 ty: Ty,
63}
64
65impl<F> QPathTyBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -070066 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -070067{
68 /// Build a qualified path with a path builder.
69 pub fn as_(self) -> PathBuilder<Self> {
70 PathBuilder::with_callback(self)
71 }
72
73 pub fn id<T>(self, id: T) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -070074 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070075 {
76 let path = Path {
77 global: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070078 segments: Delimited::new(),
79 leading_colon: None,
David Tolnay55337722016-09-11 12:58:56 -070080 };
81 self.as_().build(path).id(id)
82 }
83
84 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
David Tolnaydaaf7742016-10-03 11:11:43 -070085 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -070086 {
87 let path = Path {
88 global: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070089 segments: Delimited::new(),
90 leading_colon: None,
David Tolnay55337722016-09-11 12:58:56 -070091 };
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(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700107 as_token: Default::default(),
108 gt_token: Default::default(),
109 lt_token: Default::default(),
David Tolnay55337722016-09-11 12:58:56 -0700110 },
111 path: path,
112 }
113 }
114}
115
David Tolnaydaaf7742016-10-03 11:11:43 -0700116// ////////////////////////////////////////////////////////////////////////////
David Tolnay55337722016-09-11 12:58:56 -0700117
118pub struct QPathQSelfBuilder<F> {
119 builder: QPathBuilder<F>,
120 qself: QSelf,
121 path: Path,
122}
123
124impl<F> QPathQSelfBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700125 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -0700126{
127 pub fn id<T>(self, id: T) -> F::Result
David Tolnaydaaf7742016-10-03 11:11:43 -0700128 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700129 {
130 self.segment(id).build()
131 }
132
133 pub fn segment<T>(self, id: T) -> PathSegmentBuilder<QPathQSelfBuilder<F>>
David Tolnaydaaf7742016-10-03 11:11:43 -0700134 where T: ToIdent
David Tolnay55337722016-09-11 12:58:56 -0700135 {
136 PathSegmentBuilder::with_callback(id, self)
137 }
138}
139
140impl<F> Invoke<PathSegment> for QPathQSelfBuilder<F>
David Tolnaydaaf7742016-10-03 11:11:43 -0700141 where F: Invoke<(QSelf, Path)>
David Tolnay55337722016-09-11 12:58:56 -0700142{
143 type Result = F::Result;
144
145 fn invoke(mut self, segment: PathSegment) -> F::Result {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700146 self.path.segments.push_default(segment);
David Tolnay55337722016-09-11 12:58:56 -0700147 self.builder.build(self.qself, self.path)
148 }
149}