1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::combinator::map;
use nom::sequence::{pair, preceded, tuple};
use nom::IResult;
use crate::basic::{Identifier, Literal, Separator};
use crate::Parser;
#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
pub struct Include<'a>(Literal<'a>);
impl<'a> Parser<'a> for Include<'a> {
fn parse(input: &'a str) -> IResult<&'a str, Self> {
map(
preceded(pair(tag("include"), Separator::parse), Literal::parse),
Self,
)(input)
}
}
#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
pub struct CppInclude<'a>(Literal<'a>);
impl<'a> Parser<'a> for CppInclude<'a> {
fn parse(input: &'a str) -> IResult<&'a str, Self> {
map(
preceded(pair(tag("cpp_include"), Separator::parse), Literal::parse),
Self,
)(input)
}
}
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Namespace<'a> {
pub scope: NamespaceScope<'a>,
pub name: Identifier<'a>,
}
#[derive(derive_newtype::NewType, Eq, PartialEq, Debug, Clone)]
pub struct NamespaceScope<'a>(&'a str);
impl<'a> Parser<'a> for Namespace<'a> {
fn parse(input: &'a str) -> IResult<&'a str, Self> {
map(
tuple((
tag("namespace"),
preceded(Separator::parse, NamespaceScope::parse),
preceded(Separator::parse, Identifier::parse),
)),
|(_, scope, name)| Self { scope, name },
)(input)
}
}
impl<'a> Parser<'a> for NamespaceScope<'a> {
fn parse(input: &'a str) -> IResult<&'a str, Self> {
map(
alt((
tag("*"),
tag("c_glib"),
tag("rust"),
tag("cpp"),
tag("delphi"),
tag("haxe"),
tag("go"),
tag("java"),
tag("js"),
tag("lua"),
tag("netstd"),
tag("perl"),
tag("php"),
tag("py"),
tag("py.twisted"),
tag("rb"),
tag("st"),
tag("xsd"),
)),
Self,
)(input)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_include() {
assert_eq!(
Include::parse("include 'another.thrift'").unwrap().1,
Include::from(Literal::from("another.thrift"))
)
}
#[test]
fn test_namespace() {
assert_eq!(
Namespace::parse("namespace * MyNamespace").unwrap().1,
Namespace {
scope: NamespaceScope::from("*"),
name: Identifier::from("MyNamespace")
}
)
}
}