1use nom::branch::alt;
2use nom::combinator::{map, opt};
3use nom::multi::many0;
4use nom::sequence::delimited;
5use nom::IResult;
6
7use crate::basic::Separator;
8use crate::definition::{
9 Const, ConstRef, Enum, EnumRef, Exception, ExceptionRef, Service, ServiceRef, Struct,
10 StructRef, Typedef, TypedefRef, Union, UnionRef,
11};
12use crate::header::{CppInclude, CppIncludeRef, Include, IncludeRef, Namespace, NamespaceRef};
13use crate::Parser;
14
15#[derive(PartialEq, Debug, Clone, Default)]
16pub struct DocumentRef<'a> {
17 pub includes: Vec<IncludeRef<'a>>,
18 pub cpp_includes: Vec<CppIncludeRef<'a>>,
19 pub namespaces: Vec<NamespaceRef<'a>>,
20 pub typedefs: Vec<TypedefRef<'a>>,
21 pub consts: Vec<ConstRef<'a>>,
22 pub enums: Vec<EnumRef<'a>>,
23 pub structs: Vec<StructRef<'a>>,
24 pub unions: Vec<UnionRef<'a>>,
25 pub exceptions: Vec<ExceptionRef<'a>>,
26 pub services: Vec<ServiceRef<'a>>,
27}
28
29impl<'a> Parser<'a> for DocumentRef<'a> {
30 fn parse(input: &'a str) -> IResult<&'a str, Self> {
31 let mut target = Self::default();
32 let includes = &mut target.includes;
33 let cpp_includes = &mut target.cpp_includes;
34 let namespaces = &mut target.namespaces;
35 let typedefs = &mut target.typedefs;
36 let consts = &mut target.consts;
37 let enums = &mut target.enums;
38 let structs = &mut target.structs;
39 let unions = &mut target.unions;
40 let exceptions = &mut target.exceptions;
41 let services = &mut target.services;
42
43 let (remains, _) = many0(delimited(
44 opt(Separator::parse),
45 alt((
46 map(IncludeRef::parse, |i| includes.push(i)),
47 map(CppIncludeRef::parse, |i| cpp_includes.push(i)),
48 map(NamespaceRef::parse, |i| namespaces.push(i)),
49 map(TypedefRef::parse, |i| typedefs.push(i)),
50 map(ConstRef::parse, |i| consts.push(i)),
51 map(EnumRef::parse, |i| enums.push(i)),
52 map(StructRef::parse, |i| structs.push(i)),
53 map(UnionRef::parse, |i| unions.push(i)),
54 map(ExceptionRef::parse, |i| exceptions.push(i)),
55 map(ServiceRef::parse, |i| services.push(i)),
56 )),
57 opt(Separator::parse),
58 ))(input)?;
59 Ok((remains, target))
60 }
61}
62
63#[derive(PartialEq, Debug, Clone, Default)]
64pub struct Document {
65 pub includes: Vec<Include>,
66 pub cpp_includes: Vec<CppInclude>,
67 pub namespaces: Vec<Namespace>,
68 pub typedefs: Vec<Typedef>,
69 pub consts: Vec<Const>,
70 pub enums: Vec<Enum>,
71 pub structs: Vec<Struct>,
72 pub unions: Vec<Union>,
73 pub exceptions: Vec<Exception>,
74 pub services: Vec<Service>,
75}
76
77impl<'a> From<DocumentRef<'a>> for Document {
78 fn from(r: DocumentRef<'a>) -> Self {
79 Self {
80 includes: r.includes.into_iter().map(Into::into).collect(),
81 cpp_includes: r.cpp_includes.into_iter().map(Into::into).collect(),
82 namespaces: r.namespaces.into_iter().map(Into::into).collect(),
83 typedefs: r.typedefs.into_iter().map(Into::into).collect(),
84 consts: r.consts.into_iter().map(Into::into).collect(),
85 enums: r.enums.into_iter().map(Into::into).collect(),
86 structs: r.structs.into_iter().map(Into::into).collect(),
87 unions: r.unions.into_iter().map(Into::into).collect(),
88 exceptions: r.exceptions.into_iter().map(Into::into).collect(),
89 services: r.services.into_iter().map(Into::into).collect(),
90 }
91 }
92}
93
94impl<'a> Parser<'a> for Document {
95 fn parse(input: &'a str) -> IResult<&'a str, Self> {
96 DocumentRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use crate::basic::LiteralRef;
103
104 use super::*;
105
106 #[test]
107 fn test_document() {
108 let expected = DocumentRef {
109 includes: vec![IncludeRef::from(LiteralRef::from("another.thrift"))],
110 ..Default::default()
111 };
112 assert_eq!(
113 DocumentRef::parse("include 'another.thrift'").unwrap().1,
114 expected
115 );
116 }
117}