1use nom::branch::alt;
2use nom::bytes::complete::tag;
3use nom::combinator::map;
4use nom::sequence::{pair, preceded, tuple};
5use nom::IResult;
6
7use crate::basic::{Identifier, IdentifierRef, Literal, LiteralRef, Separator};
8use crate::Parser;
9
10#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
12pub struct IncludeRef<'a>(LiteralRef<'a>);
13
14impl<'a> Parser<'a> for IncludeRef<'a> {
15 fn parse(input: &'a str) -> IResult<&'a str, Self> {
16 map(
17 preceded(pair(tag("include"), Separator::parse), LiteralRef::parse),
18 Self,
19 )(input)
20 }
21}
22
23#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
24pub struct Include(Literal);
25
26impl<'a> From<IncludeRef<'a>> for Include {
27 fn from(r: IncludeRef<'a>) -> Self {
28 Self(r.0.into())
29 }
30}
31
32impl<'a> Parser<'a> for Include {
33 fn parse(input: &'a str) -> IResult<&'a str, Self> {
34 IncludeRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
35 }
36}
37
38#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
40pub struct CppIncludeRef<'a>(LiteralRef<'a>);
41
42impl<'a> Parser<'a> for CppIncludeRef<'a> {
43 fn parse(input: &'a str) -> IResult<&'a str, Self> {
44 map(
45 preceded(
46 pair(tag("cpp_include"), Separator::parse),
47 LiteralRef::parse,
48 ),
49 Self,
50 )(input)
51 }
52}
53
54#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
55pub struct CppInclude(Literal);
56
57impl<'a> From<CppIncludeRef<'a>> for CppInclude {
58 fn from(r: CppIncludeRef<'a>) -> Self {
59 Self(r.0.into())
60 }
61}
62
63impl<'a> Parser<'a> for CppInclude {
64 fn parse(input: &'a str) -> IResult<&'a str, Self> {
65 CppIncludeRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
66 }
67}
68
69#[derive(Eq, PartialEq, Debug, Clone)]
71pub struct NamespaceRef<'a> {
72 pub scope: NamespaceScopeRef<'a>,
73 pub name: IdentifierRef<'a>,
74}
75
76#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
80pub struct NamespaceScopeRef<'a>(&'a str);
81
82impl<'a> Parser<'a> for NamespaceRef<'a> {
83 fn parse(input: &'a str) -> IResult<&'a str, Self> {
84 map(
85 tuple((
86 tag("namespace"),
87 preceded(Separator::parse, NamespaceScopeRef::parse),
88 preceded(Separator::parse, IdentifierRef::parse),
89 )),
90 |(_, scope, name)| Self { scope, name },
91 )(input)
92 }
93}
94
95impl<'a> Parser<'a> for NamespaceScopeRef<'a> {
96 fn parse(input: &'a str) -> IResult<&'a str, Self> {
97 map(
98 alt((
99 tag("*"),
100 tag("c_glib"),
101 tag("rust"),
102 tag("cpp"),
103 tag("delphi"),
104 tag("haxe"),
105 tag("go"),
106 tag("java"),
107 tag("js"),
108 tag("lua"),
109 tag("netstd"),
110 tag("perl"),
111 tag("php"),
112 tag("py"),
113 tag("py.twisted"),
114 tag("rb"),
115 tag("st"),
116 tag("xsd"),
117 )),
118 Self,
119 )(input)
120 }
121}
122
123#[derive(Eq, PartialEq, Debug, Clone)]
124pub struct Namespace {
125 pub scope: NamespaceScope,
126 pub name: Identifier,
127}
128
129#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
130pub struct NamespaceScope(String);
131
132impl<'a> From<NamespaceRef<'a>> for Namespace {
133 fn from(r: NamespaceRef<'a>) -> Self {
134 Self {
135 scope: r.scope.into(),
136 name: r.name.into(),
137 }
138 }
139}
140
141impl<'a> From<NamespaceScopeRef<'a>> for NamespaceScope {
142 fn from(r: NamespaceScopeRef<'a>) -> Self {
143 Self(r.0.into())
144 }
145}
146
147impl<'a> Parser<'a> for Namespace {
148 fn parse(input: &'a str) -> IResult<&'a str, Self> {
149 NamespaceRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
150 }
151}
152
153impl<'a> Parser<'a> for NamespaceScope {
154 fn parse(input: &'a str) -> IResult<&'a str, Self> {
155 NamespaceScopeRef::parse(input).map(|(remains, parsed)| (remains, parsed.into()))
156 }
157}
158
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 #[test]
164 fn test_include() {
165 assert_eq!(
166 IncludeRef::parse("include 'another.thrift'").unwrap().1,
167 IncludeRef::from(LiteralRef::from("another.thrift"))
168 )
169 }
170
171 #[test]
172 fn test_namespace() {
173 assert_eq!(
174 NamespaceRef::parse("namespace * MyNamespace").unwrap().1,
175 NamespaceRef {
176 scope: NamespaceScopeRef::from("*"),
177 name: IdentifierRef::from("MyNamespace")
178 }
179 )
180 }
181}