1use nom::branch::alt;
2use nom::bytes::complete::tag;
3use nom::character::complete::char as cchar;
4use nom::combinator::{map, opt};
5use nom::multi::separated_list0;
6use nom::sequence::{delimited, pair, preceded, tuple};
7use nom::IResult;
8
9use crate::basic::{Identifier, IdentifierRef, ListSeparator, Separator};
10use crate::constant::{parse_list_separator, ConstValue, ConstValueRef, IntConstant};
11use crate::field::{Field, FieldRef};
12use crate::functions::{Function, FunctionRef};
13use crate::types::{FieldType, FieldTypeRef};
14use crate::Parser;
15
16#[derive(Debug, Clone, PartialEq)]
18pub struct ConstRef<'a> {
19 pub name: IdentifierRef<'a>,
20 pub type_: FieldTypeRef<'a>,
21 pub value: ConstValueRef<'a>,
22}
23
24impl<'a> Parser<'a> for ConstRef<'a> {
25 fn parse(input: &'a str) -> IResult<&'a str, Self> {
26 map(
27 tuple((
28 tag("const"),
29 preceded(Separator::parse, FieldTypeRef::parse),
30 preceded(Separator::parse, IdentifierRef::parse),
31 preceded(opt(Separator::parse), cchar('=')),
32 preceded(opt(Separator::parse), ConstValueRef::parse),
33 opt(pair(opt(Separator::parse), ListSeparator::parse)),
34 )),
35 |(_, type_, name, _, value, _)| Self { name, type_, value },
36 )(input)
37 }
38}
39
40#[derive(Debug, Clone, PartialEq)]
41pub struct Const {
42 pub name: Identifier,
43 pub type_: FieldType,
44 pub value: ConstValue,
45}
46
47impl<'a> From<ConstRef<'a>> for Const {
48 fn from(r: ConstRef<'a>) -> Self {
49 Self {
50 name: r.name.into(),
51 type_: r.type_.into(),
52 value: r.value.into(),
53 }
54 }
55}
56
57impl<'a> Parser<'a> for Const {
58 fn parse(input: &'a str) -> IResult<&'a str, Self> {
59 ConstRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
60 }
61}
62
63#[derive(Debug, Clone, PartialEq)]
68pub struct TypedefRef<'a> {
69 pub old: FieldTypeRef<'a>,
70 pub alias: IdentifierRef<'a>,
71}
72
73impl<'a> Parser<'a> for TypedefRef<'a> {
74 fn parse(input: &'a str) -> IResult<&'a str, Self> {
75 map(
76 tuple((
77 tag("typedef"),
78 preceded(
79 Separator::parse,
80 alt((
81 FieldTypeRef::parse_base_type,
82 FieldTypeRef::parse_container_type,
83 )),
84 ),
85 preceded(Separator::parse, IdentifierRef::parse),
86 )),
87 |(_, old, alias)| Self { old, alias },
88 )(input)
89 }
90}
91
92#[derive(Debug, Clone, PartialEq)]
93pub struct Typedef {
94 pub old: FieldType,
95 pub alias: Identifier,
96}
97
98impl<'a> From<TypedefRef<'a>> for Typedef {
99 fn from(r: TypedefRef<'a>) -> Self {
100 Self {
101 old: r.old.into(),
102 alias: r.alias.into(),
103 }
104 }
105}
106
107impl<'a> Parser<'a> for Typedef {
108 fn parse(input: &'a str) -> IResult<&'a str, Self> {
109 TypedefRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
110 }
111}
112
113#[derive(Debug, Clone, PartialEq)]
115pub struct EnumRef<'a> {
116 pub name: IdentifierRef<'a>,
117 pub children: Vec<EnumValueRef<'a>>,
118}
119
120#[derive(Debug, Clone, PartialEq)]
121pub struct EnumValueRef<'a> {
122 pub name: IdentifierRef<'a>,
123 pub value: Option<IntConstant>,
124}
125
126impl<'a> Parser<'a> for EnumRef<'a> {
127 fn parse(input: &'a str) -> IResult<&'a str, Self> {
128 map(
129 tuple((
130 tag("enum"),
131 preceded(Separator::parse, IdentifierRef::parse),
132 tuple((opt(Separator::parse), cchar('{'), opt(Separator::parse))),
133 separated_list0(parse_list_separator, EnumValueRef::parse),
134 preceded(opt(Separator::parse), cchar('}')),
135 )),
136 |(_, name, _, children, _)| Self { name, children },
137 )(input)
138 }
139}
140
141impl<'a> Parser<'a> for EnumValueRef<'a> {
142 fn parse(input: &'a str) -> IResult<&'a str, Self> {
143 map(
144 tuple((
145 IdentifierRef::parse,
146 opt(map(
147 tuple((
148 opt(Separator::parse),
149 cchar('='),
150 opt(Separator::parse),
151 IntConstant::parse,
152 )),
153 |(_, _, _, i)| (i),
154 )),
155 )),
156 |(name, value)| Self { name, value },
157 )(input)
158 }
159}
160
161#[derive(Debug, Clone, PartialEq)]
162pub struct Enum {
163 pub name: Identifier,
164 pub children: Vec<EnumValue>,
165}
166
167#[derive(Debug, Clone, PartialEq)]
168pub struct EnumValue {
169 pub name: Identifier,
170 pub value: Option<IntConstant>,
171}
172
173impl<'a> From<EnumRef<'a>> for Enum {
174 fn from(r: EnumRef<'a>) -> Self {
175 Self {
176 name: r.name.into(),
177 children: r.children.into_iter().map(Into::into).collect(),
178 }
179 }
180}
181
182impl<'a> From<EnumValueRef<'a>> for EnumValue {
183 fn from(r: EnumValueRef<'a>) -> Self {
184 Self {
185 name: r.name.into(),
186 value: r.value,
187 }
188 }
189}
190
191impl<'a> Parser<'a> for Enum {
192 fn parse(input: &'a str) -> IResult<&'a str, Self> {
193 EnumRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
194 }
195}
196
197impl<'a> Parser<'a> for EnumValue {
198 fn parse(input: &'a str) -> IResult<&'a str, Self> {
199 EnumValueRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
200 }
201}
202
203#[derive(Debug, Clone, PartialEq)]
205pub struct StructRef<'a> {
206 pub name: IdentifierRef<'a>,
207 pub fields: Vec<FieldRef<'a>>,
208}
209
210impl<'a> Parser<'a> for StructRef<'a> {
211 fn parse(input: &'a str) -> IResult<&'a str, Self> {
212 map(
213 tuple((
214 pair(tag("struct"), Separator::parse),
215 IdentifierRef::parse,
216 delimited(opt(Separator::parse), cchar('{'), opt(Separator::parse)),
217 separated_list0(Separator::parse, FieldRef::parse),
218 pair(opt(Separator::parse), cchar('}')),
219 )),
220 |(_, name, _, fields, _)| Self { name, fields },
221 )(input)
222 }
223}
224
225#[derive(Debug, Clone, PartialEq)]
226pub struct Struct {
227 pub name: Identifier,
228 pub fields: Vec<Field>,
229}
230
231impl<'a> From<StructRef<'a>> for Struct {
232 fn from(r: StructRef<'a>) -> Self {
233 Self {
234 name: r.name.into(),
235 fields: r.fields.into_iter().map(Into::into).collect(),
236 }
237 }
238}
239
240impl<'a> Parser<'a> for Struct {
241 fn parse(input: &'a str) -> IResult<&'a str, Self> {
242 StructRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
243 }
244}
245
246#[derive(Debug, Clone, PartialEq)]
248pub struct UnionRef<'a> {
249 pub name: IdentifierRef<'a>,
250 pub fields: Vec<FieldRef<'a>>,
251}
252
253impl<'a> Parser<'a> for UnionRef<'a> {
254 fn parse(input: &'a str) -> IResult<&'a str, Self> {
255 map(
256 tuple((
257 pair(tag("union"), Separator::parse),
258 IdentifierRef::parse,
259 delimited(opt(Separator::parse), cchar('{'), opt(Separator::parse)),
260 separated_list0(Separator::parse, FieldRef::parse),
261 pair(opt(Separator::parse), cchar('}')),
262 )),
263 |(_, name, _, fields, _)| Self { name, fields },
264 )(input)
265 }
266}
267
268#[derive(Debug, Clone, PartialEq)]
269pub struct Union {
270 pub name: Identifier,
271 pub fields: Vec<Field>,
272}
273
274impl<'a> From<UnionRef<'a>> for Union {
275 fn from(r: UnionRef<'a>) -> Self {
276 Self {
277 name: r.name.into(),
278 fields: r.fields.into_iter().map(Into::into).collect(),
279 }
280 }
281}
282
283impl<'a> Parser<'a> for Union {
284 fn parse(input: &'a str) -> IResult<&'a str, Self> {
285 UnionRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
286 }
287}
288
289#[derive(Debug, Clone, PartialEq)]
291pub struct ExceptionRef<'a> {
292 pub name: IdentifierRef<'a>,
293 pub fields: Vec<FieldRef<'a>>,
294}
295
296impl<'a> Parser<'a> for ExceptionRef<'a> {
297 fn parse(input: &'a str) -> IResult<&'a str, Self> {
298 map(
299 tuple((
300 pair(tag("exception"), Separator::parse),
301 IdentifierRef::parse,
302 delimited(opt(Separator::parse), cchar('{'), opt(Separator::parse)),
303 separated_list0(Separator::parse, FieldRef::parse),
304 pair(opt(Separator::parse), cchar('}')),
305 )),
306 |(_, name, _, fields, _)| Self { name, fields },
307 )(input)
308 }
309}
310
311#[derive(Debug, Clone, PartialEq)]
312pub struct Exception {
313 pub name: Identifier,
314 pub fields: Vec<Field>,
315}
316
317impl<'a> From<ExceptionRef<'a>> for Exception {
318 fn from(r: ExceptionRef<'a>) -> Self {
319 Self {
320 name: r.name.into(),
321 fields: r.fields.into_iter().map(Into::into).collect(),
322 }
323 }
324}
325
326impl<'a> Parser<'a> for Exception {
327 fn parse(input: &'a str) -> IResult<&'a str, Self> {
328 ExceptionRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
329 }
330}
331
332#[derive(Debug, Clone, PartialEq)]
334pub struct ServiceRef<'a> {
335 pub name: IdentifierRef<'a>,
336 pub extension: Option<IdentifierRef<'a>>,
337 pub functions: Vec<FunctionRef<'a>>,
338}
339
340impl<'a> Parser<'a> for ServiceRef<'a> {
341 fn parse(input: &'a str) -> IResult<&'a str, Self> {
342 map(
343 tuple((
344 delimited(
345 pair(tag("service"), Separator::parse),
346 IdentifierRef::parse,
347 opt(Separator::parse),
348 ),
349 opt(map(
350 tuple((
351 tag("extends"),
352 Separator::parse,
353 IdentifierRef::parse,
354 opt(Separator::parse),
355 )),
356 |(_, _, ext, _)| ext,
357 )),
358 delimited(
359 pair(cchar('{'), opt(Separator::parse)),
360 separated_list0(Separator::parse, FunctionRef::parse),
361 pair(opt(Separator::parse), cchar('}')),
362 ),
363 )),
364 |(name, extension, functions)| Self {
365 name,
366 extension,
367 functions,
368 },
369 )(input)
370 }
371}
372
373#[derive(Debug, Clone, PartialEq)]
374pub struct Service {
375 pub name: Identifier,
376 pub extension: Option<Identifier>,
377 pub functions: Vec<Function>,
378}
379
380impl<'a> From<ServiceRef<'a>> for Service {
381 fn from(r: ServiceRef<'a>) -> Self {
382 Self {
383 name: r.name.into(),
384 extension: r.extension.map(Into::into),
385 functions: r.functions.into_iter().map(Into::into).collect(),
386 }
387 }
388}
389
390impl<'a> Parser<'a> for Service {
391 fn parse(input: &'a str) -> IResult<&'a str, Self> {
392 ServiceRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
393 }
394}
395
396#[cfg(test)]
397mod test {
398 use crate::basic::LiteralRef;
399
400 use super::*;
401
402 #[test]
403 fn test_const() {
404 assert_eq!(
405 ConstRef::parse("const bool is_rust_easy = 'yes!';")
406 .unwrap()
407 .1,
408 ConstRef {
409 name: IdentifierRef::from("is_rust_easy"),
410 type_: FieldTypeRef::Bool,
411 value: ConstValueRef::Literal(LiteralRef::from("yes!"))
412 }
413 );
414 }
415
416 #[test]
417 fn test_typedef() {
418 assert_eq!(
419 TypedefRef::parse("typedef i32 MyI32").unwrap().1,
420 TypedefRef {
421 old: FieldTypeRef::I32,
422 alias: IdentifierRef::from("MyI32")
423 }
424 );
425 }
426
427 #[test]
428 fn test_enum() {
429 let expected = EnumRef {
430 name: IdentifierRef::from("PL"),
431 children: vec![
432 EnumValueRef {
433 name: IdentifierRef::from("Rust"),
434 value: None,
435 },
436 EnumValueRef {
437 name: IdentifierRef::from("Go"),
438 value: Some(IntConstant::from(2)),
439 },
440 EnumValueRef {
441 name: IdentifierRef::from("Cpp"),
442 value: Some(IntConstant::from(3)),
443 },
444 ],
445 };
446 assert_eq!(
447 EnumRef::parse("enum PL { Rust Go=2 , Cpp = 3 }").unwrap().1,
448 expected
449 );
450 assert_eq!(
451 EnumRef::parse("enum PL{Rust Go=2,Cpp=3}").unwrap().1,
452 expected
453 );
454 }
455
456 #[test]
457 fn test_struct() {
458 let expected = StructRef {
459 name: IdentifierRef::from("user"),
460 fields: vec![
461 FieldRef {
462 id: Some(IntConstant::from(1)),
463 required: Some(false),
464 type_: FieldTypeRef::String,
465 name: IdentifierRef::from("name"),
466 default: None,
467 },
468 FieldRef {
469 id: Some(IntConstant::from(2)),
470 required: None,
471 type_: FieldTypeRef::I32,
472 name: IdentifierRef::from("age"),
473 default: Some(ConstValueRef::Int(IntConstant::from(18))),
474 },
475 ],
476 };
477 assert_eq!(
478 StructRef::parse("struct user{1:optional string name; 2:i32 age=18}")
479 .unwrap()
480 .1,
481 expected
482 );
483 assert_eq!(
484 StructRef::parse("struct user { 1 : optional string name ; 2 : i32 age = 18 }")
485 .unwrap()
486 .1,
487 expected
488 );
489 }
490
491 #[test]
492 fn test_service() {
493 let function = FunctionRef {
494 oneway: false,
495 returns: Some(FieldTypeRef::String),
496 name: IdentifierRef::from("GetUser"),
497 parameters: vec![FieldRef {
498 id: None,
499 required: Some(true),
500 type_: FieldTypeRef::String,
501 name: IdentifierRef::from("name"),
502 default: None,
503 }],
504 exceptions: None,
505 };
506 let expected = ServiceRef {
507 name: IdentifierRef::from("DemoService"),
508 extension: Some(IdentifierRef::from("BaseService")),
509 functions: vec![function.clone(), function],
510 };
511 assert_eq!(
512 ServiceRef::parse(
513 "service DemoService extends BaseService { \
514 string GetUser(required string name),
515 string GetUser(required string name) }"
516 )
517 .unwrap()
518 .1,
519 expected
520 );
521 }
522}