keyvalues_parser/text/parse/
raw.rs1use super::*;
2
3pub type PestError = pest::error::Error<Rule>;
4type BoxedState<'a> = Box<pest::ParserState<'a, Rule>>;
5type ParseResult<'a> = pest::ParseResult<BoxedState<'a>>;
6
7common_parsing!(pest_parse, Rule, false);
8
9#[deprecated(
11 since = "0.2.3",
12 note = "Please use `Parser::new().literal_special_chars(true).parse()` instead"
13)]
14pub fn parse(s: &str) -> Result<PartialVdf<'_>> {
15 parse_(s)
16}
17
18#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
19#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
20pub enum Rule {
21 EOI,
23 WHITESPACE,
24 COMMENT,
25 vdf,
26 base_macro,
27 quoted_raw_string,
28 pairs,
29 pair,
30 key,
31 value,
32 obj,
33 quoted_string,
34 quoted_inner,
35 unquoted_string,
36 unquoted_char,
37}
38
39mod rules {
40 #![allow(non_snake_case)]
41
42 use super::{any, skip, soi, whitespace, BoxedState, ParseResult, Rule};
43
44 use pest::Atomicity;
45
46 #[inline]
47 pub fn vdf(s: BoxedState<'_>) -> ParseResult<'_> {
48 s.sequence(|s| {
49 soi(s)
50 .and_then(skip)
51 .and_then(|s| {
52 s.sequence(|s| {
53 s.optional(|s| {
54 base_macro(s).and_then(|s| {
55 s.repeat(|s| s.sequence(|s| skip(s).and_then(base_macro)))
56 })
57 })
58 })
59 })
60 .and_then(skip)
61 .and_then(pair)
62 .and_then(skip)
63 .and_then(|s| s.optional(|s| s.match_string("\0")))
64 .and_then(skip)
65 .and_then(EOI)
66 })
67 }
68 pub fn base_macro(s: BoxedState<'_>) -> ParseResult<'_> {
69 s.rule(Rule::base_macro, |s| {
70 s.sequence(|s| {
71 s.match_string("#base")
72 .and_then(skip)
73 .and_then(|s| quoted_raw_string(s).or_else(unquoted_string))
74 })
75 })
76 }
77 #[inline]
78 pub fn quoted_raw_string(s: BoxedState<'_>) -> ParseResult<'_> {
79 s.atomic(Atomicity::CompoundAtomic, |s| {
80 s.rule(Rule::quoted_raw_string, |s| {
81 s.sequence(|s| {
82 s.match_string("\"")
83 .and_then(quoted_inner)
84 .and_then(|s| s.match_string("\""))
85 })
86 })
87 })
88 }
89 #[inline]
90 pub fn pairs(s: BoxedState<'_>) -> ParseResult<'_> {
91 s.sequence(|s| {
92 s.optional(|s| {
93 pair(s).and_then(|s| s.repeat(|s| s.sequence(|s| skip(s).and_then(pair))))
94 })
95 })
96 }
97 #[inline]
98 pub fn pair(s: BoxedState<'_>) -> ParseResult<'_> {
99 s.rule(Rule::pair, |s| {
100 s.sequence(|s| key(s).and_then(skip).and_then(value))
101 })
102 }
103 #[inline]
104 pub fn key(s: BoxedState<'_>) -> ParseResult<'_> {
105 quoted_string(s).or_else(unquoted_string)
106 }
107 #[inline]
108 pub fn value(s: BoxedState<'_>) -> ParseResult<'_> {
109 quoted_string(s).or_else(obj).or_else(unquoted_string)
110 }
111 #[inline]
112 pub fn obj(s: BoxedState<'_>) -> ParseResult<'_> {
113 s.rule(Rule::obj, |s| {
114 s.sequence(|s| {
115 s.match_string("{")
116 .and_then(skip)
117 .and_then(pairs)
118 .and_then(skip)
119 .and_then(|s| s.match_string("}"))
120 })
121 })
122 }
123 #[inline]
124 pub fn quoted_string(s: BoxedState<'_>) -> ParseResult<'_> {
125 s.atomic(Atomicity::CompoundAtomic, |s| {
126 s.rule(Rule::quoted_string, |s| {
127 s.sequence(|s| {
128 s.match_string("\"")
129 .and_then(quoted_inner)
130 .and_then(|s| s.match_string("\""))
131 })
132 })
133 })
134 }
135 #[inline]
136 pub fn quoted_inner(s: BoxedState<'_>) -> ParseResult<'_> {
137 s.rule(Rule::quoted_inner, |s| {
138 s.atomic(Atomicity::Atomic, |s| s.skip_until(&["\""]))
139 })
140 }
141 #[inline]
142 pub fn unquoted_string(s: BoxedState<'_>) -> ParseResult<'_> {
143 s.rule(Rule::unquoted_string, |s| {
144 s.atomic(Atomicity::Atomic, |s| {
145 s.sequence(|s| unquoted_char(s).and_then(|s| s.repeat(unquoted_char)))
146 })
147 })
148 }
149 #[inline]
150 pub fn unquoted_char(s: BoxedState<'_>) -> ParseResult<'_> {
151 s.rule(Rule::unquoted_char, |s| {
152 s.sequence(|s| {
153 s.lookahead(false, |s| {
154 s.match_string("\"")
155 .or_else(|s| s.match_string("{"))
156 .or_else(|s| s.match_string("}"))
157 .or_else(whitespace)
158 })
159 .and_then(skip)
160 .and_then(any)
161 })
162 })
163 }
164 pub fn EOI(s: BoxedState<'_>) -> ParseResult<'_> {
165 s.rule(Rule::EOI, |s| s.end_of_input())
166 }
167}
168
169pub fn pest_parse(input: &str) -> std::result::Result<pest::iterators::Pairs<'_, Rule>, PestError> {
170 pest::state(input, rules::vdf)
171}