1use errors::Result;
4use serde::Serialize;
5use std::fmt;
6use std::vec;
7use {Diagnostics, Flavor, Loc, RpEnumBody, RpInterfaceBody, RpReg, RpServiceBody, RpSubType,
8 RpTupleBody, RpTypeBody, RpVariantRef, Span, Translate, Translator};
9
10pub struct Decls<'a, F: 'static>
12where
13 F: Flavor,
14{
15 iter: vec::IntoIter<&'a RpDecl<F>>,
16}
17
18impl<'a, F: 'static> Iterator for Decls<'a, F>
19where
20 F: Flavor,
21{
22 type Item = &'a RpDecl<F>;
23
24 fn next(&mut self) -> Option<Self::Item> {
25 self.iter.next()
26 }
27}
28
29#[derive(Debug, Clone)]
30pub enum RpNamed<'a, F: 'static>
31where
32 F: Flavor,
33{
34 Type(&'a Loc<RpTypeBody<F>>),
35 Tuple(&'a Loc<RpTupleBody<F>>),
36 Interface(&'a Loc<RpInterfaceBody<F>>),
37 SubType(&'a Loc<RpSubType<F>>),
38 Enum(&'a Loc<RpEnumBody<F>>),
39 EnumVariant(RpVariantRef<'a, F>),
40 Service(&'a Loc<RpServiceBody<F>>),
41}
42
43impl<'a, F: 'static> RpNamed<'a, F>
44where
45 F: Flavor,
46{
47 pub fn name(&self) -> &F::Name {
49 use self::RpNamed::*;
50
51 match *self {
52 Type(ref body) => &body.name,
53 Tuple(ref tuple) => &tuple.name,
54 Interface(ref interface) => &interface.name,
55 SubType(ref sub_type) => &sub_type.name,
56 Enum(ref en) => &en.name,
57 EnumVariant(ref variant) => variant.name,
58 Service(ref service) => &service.name,
59 }
60 }
61
62 pub fn span(&self) -> Span {
64 use self::RpNamed::*;
65
66 match *self {
67 Type(ref body) => Loc::span(body),
68 Tuple(ref tuple) => Loc::span(tuple),
69 Interface(ref interface) => Loc::span(interface),
70 SubType(ref sub_type) => Loc::span(sub_type),
71 Enum(ref en) => Loc::span(en),
72 EnumVariant(ref variant) => variant.span,
73 Service(ref service) => Loc::span(service),
74 }
75 }
76}
77
78#[derive(Debug, Clone, Serialize)]
79#[serde(bound = "F: Serialize, F::Field: Serialize, F::Endpoint: Serialize, F::Package: \
80 Serialize, F::Name: Serialize, F::EnumType: Serialize")]
81#[serde(tag = "type", rename_all = "snake_case")]
82pub enum RpDecl<F: 'static>
83where
84 F: Flavor,
85{
86 Type(Loc<RpTypeBody<F>>),
87 Tuple(Loc<RpTupleBody<F>>),
88 Interface(Loc<RpInterfaceBody<F>>),
89 Enum(Loc<RpEnumBody<F>>),
90 Service(Loc<RpServiceBody<F>>),
91}
92
93impl<F: 'static> RpDecl<F>
94where
95 F: Flavor,
96{
97 pub fn decls(&self) -> Decls<F> {
98 use self::RpDecl::*;
99
100 let iter = match *self {
101 Type(ref body) => body.decls.iter().collect::<Vec<_>>().into_iter(),
102 Interface(ref body) => {
103 let mut decls = body.decls.iter().collect::<Vec<_>>();
104 decls.extend(body.sub_types.iter().flat_map(|s| s.decls.iter()));
105 decls.into_iter()
106 }
107 Enum(ref body) => body.decls.iter().collect::<Vec<_>>().into_iter(),
108 Tuple(ref body) => body.decls.iter().collect::<Vec<_>>().into_iter(),
109 Service(ref body) => body.decls.iter().collect::<Vec<_>>().into_iter(),
110 };
111
112 Decls { iter: iter }
113 }
114
115 pub fn ident(&self) -> &str {
116 use self::RpDecl::*;
117
118 match *self {
119 Type(ref body) => body.ident.as_str(),
120 Interface(ref body) => body.ident.as_str(),
121 Enum(ref body) => body.ident.as_str(),
122 Tuple(ref body) => body.ident.as_str(),
123 Service(ref body) => body.ident.as_str(),
124 }
125 }
126
127 pub fn name(&self) -> &F::Name {
128 use self::RpDecl::*;
129
130 match *self {
131 Type(ref body) => &body.name,
132 Interface(ref body) => &body.name,
133 Enum(ref body) => &body.name,
134 Tuple(ref body) => &body.name,
135 Service(ref body) => &body.name,
136 }
137 }
138
139 pub fn comment(&self) -> &[String] {
140 use self::RpDecl::*;
141
142 match *self {
143 Type(ref body) => &body.comment,
144 Interface(ref body) => &body.comment,
145 Enum(ref body) => &body.comment,
146 Tuple(ref body) => &body.comment,
147 Service(ref body) => &body.comment,
148 }
149 }
150
151 pub fn to_reg(&self) -> Vec<(&F::Name, Span, RpReg)> {
153 use self::RpDecl::*;
154
155 let mut out = Vec::new();
156
157 match *self {
158 Type(ref ty) => {
159 out.push((&ty.name, Loc::span(ty), RpReg::Type));
160 }
161 Interface(ref interface) => {
162 for sub_type in interface.sub_types.iter() {
163 out.push((&sub_type.name, Loc::span(sub_type), RpReg::SubType));
164 }
165
166 out.push((&interface.name, Loc::span(interface), RpReg::Interface));
167 }
168 Enum(ref en) => {
169 for variant in &en.variants {
170 out.push((variant.name, variant.span, RpReg::EnumVariant));
171 }
172
173 out.push((&en.name, Loc::span(en), RpReg::Enum));
174 }
175 Tuple(ref tuple) => {
176 out.push((&tuple.name, Loc::span(tuple), RpReg::Tuple));
177 }
178 Service(ref service) => {
179 out.push((&service.name, Loc::span(service), RpReg::Service));
180 }
181 }
182
183 out.extend(self.decls().flat_map(|d| d.to_reg()));
184 out
185 }
186
187 pub fn to_named(&self) -> Vec<RpNamed<F>> {
189 use self::RpDecl::*;
190
191 let mut out = Vec::new();
192
193 match *self {
194 Type(ref ty) => {
195 out.push(RpNamed::Type(ty));
196 }
197 Interface(ref interface) => {
198 for sub_type in interface.sub_types.iter() {
199 out.push(RpNamed::SubType(sub_type));
200 }
201
202 out.push(RpNamed::Interface(interface));
203 }
204 Enum(ref en) => {
205 for variant in &en.variants {
206 out.push(RpNamed::EnumVariant(variant));
207 }
208
209 out.push(RpNamed::Enum(en));
210 }
211 Tuple(ref tuple) => {
212 out.push(RpNamed::Tuple(tuple));
213 }
214 Service(ref service) => {
215 out.push(RpNamed::Service(service));
216 }
217 }
218
219 out.extend(self.decls().flat_map(|d| d.to_named()));
220 out
221 }
222
223 pub fn kind(&self) -> &str {
225 use self::RpDecl::*;
226
227 match *self {
228 Type(_) => "type",
229 Interface(_) => "interface",
230 Enum(_) => "enum",
231 Tuple(_) => "tuple",
232 Service(_) => "service",
233 }
234 }
235
236 pub fn span(&self) -> Span {
238 use self::RpDecl::*;
239
240 match *self {
241 Type(ref body) => Loc::span(body),
242 Interface(ref body) => Loc::span(body),
243 Enum(ref body) => Loc::span(body),
244 Tuple(ref body) => Loc::span(body),
245 Service(ref body) => Loc::span(body),
246 }
247 }
248}
249
250impl<F: 'static, T> Translate<T> for RpDecl<F>
251where
252 F: Flavor,
253 T: Translator<Source = F>,
254{
255 type Source = F;
256 type Out = RpDecl<T::Target>;
257
258 fn translate(self, diag: &mut Diagnostics, translator: &T) -> Result<RpDecl<T::Target>> {
260 use self::RpDecl::*;
261
262 let out = match self {
263 Type(body) => Type(body.translate(diag, translator)?),
264 Tuple(body) => Tuple(body.translate(diag, translator)?),
265 Interface(body) => Interface(body.translate(diag, translator)?),
266 Enum(body) => Enum(body.translate(diag, translator)?),
267 Service(body) => Service(body.translate(diag, translator)?),
268 };
269
270 Ok(out)
271 }
272}
273
274impl<F: 'static> fmt::Display for RpDecl<F>
275where
276 F: Flavor,
277{
278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
279 use self::RpDecl::*;
280
281 match *self {
282 Type(ref body) => write!(f, "type {}", body.name),
283 Interface(ref body) => write!(f, "interface {}", body.name),
284 Enum(ref body) => write!(f, "enum {}", body.name),
285 Tuple(ref body) => write!(f, "tuple {}", body.name),
286 Service(ref body) => write!(f, "service {}", body.name),
287 }
288 }
289}
290
291impl<'a, F: 'static> From<&'a RpDecl<F>> for Span
292where
293 F: Flavor,
294{
295 fn from(value: &'a RpDecl<F>) -> Self {
296 value.span().clone()
297 }
298}