1use crate::ast::{Block, Inline};
2use nom::{
3 branch::alt,
4 character::complete::{anychar, line_ending, not_line_ending, space0},
5 combinator::{eof, fail, not, recognize, value},
6 multi::{many0, many1},
7 sequence::{preceded, terminated},
8 IResult, Parser,
9};
10
11pub(crate) fn eof_or_eol(input: &str) -> IResult<&str, &str> {
12 alt((line_ending, eof)).parse(input)
13}
14
15pub(crate) fn many_empty_lines0(input: &str) -> IResult<&str, Vec<&str>> {
16 many0(preceded(space0, eof_or_eol)).parse(input)
17}
18
19pub(crate) fn not_eof_or_eol1(input: &str) -> IResult<&str, &str> {
20 recognize(many1(preceded(not(eof_or_eol), anychar))).parse(input)
21}
22
23pub(crate) fn not_eof_or_eol0(input: &str) -> IResult<&str, &str> {
24 alt((not_line_ending, eof)).parse(input)
25}
26
27pub(crate) fn line_terminated<'a, O, P>(
28 inner: P,
29) -> impl Parser<&'a str, Output = O, Error = nom::error::Error<&'a str>>
30where
31 P: Parser<&'a str, Output = O, Error = nom::error::Error<&'a str>>,
32{
33 terminated(inner, eof_or_eol)
34}
35
36pub(crate) fn conditional<'a, O, P>(
53 behavior: crate::parser::config::ElementBehavior<O>,
54 default: Vec<O>,
55 mut inner: P,
56) -> impl Parser<&'a str, Output = Vec<O>, Error = nom::error::Error<&'a str>>
57where
58 P: Parser<&'a str, Output = O, Error = nom::error::Error<&'a str>>,
59 O: Clone,
60{
61 move |input: &'a str| {
62 let inner1 = |s: &'a str| inner.parse(s);
63 match &behavior {
64 crate::parser::config::ElementBehavior::Ignore => fail().map(|v| vec![v]).parse(input),
65 crate::parser::config::ElementBehavior::Parse => inner1.map(|v| vec![v]).parse(input),
66 crate::parser::config::ElementBehavior::Skip => {
67 value(default.clone(), inner1.map(|v| vec![v])).parse(input)
68 }
69 crate::parser::config::ElementBehavior::Map(f) => {
70 let (i, o) = inner.parse(input)?;
71 let mut f1 = (**f).borrow_mut();
72 let mapped = vec![(f1.as_mut())(o)];
73 Ok((i, mapped))
74 }
75 crate::parser::config::ElementBehavior::FlatMap(f) => {
76 let (i, o) = inner.parse(input)?;
77 let mut f1 = (**f).borrow_mut();
78 let mapped = (f1.as_mut())(o);
79 Ok((i, mapped))
80 }
81 }
82 }
83}
84
85pub(crate) fn conditional_block_unit<'a, P>(
86 behavior: crate::parser::config::ElementBehavior<Block>,
87 mut inner: P,
88) -> impl Parser<&'a str, Output = Vec<()>, Error = nom::error::Error<&'a str>>
89where
90 P: Parser<&'a str, Output = (), Error = nom::error::Error<&'a str>>,
91{
92 let behavior: crate::parser::config::ElementBehavior<()> = match behavior {
93 super::config::ElementBehavior::Parse => super::config::ElementBehavior::Parse,
94 super::config::ElementBehavior::Ignore => super::config::ElementBehavior::Ignore,
95 super::config::ElementBehavior::Skip => super::config::ElementBehavior::Skip,
96 super::config::ElementBehavior::Map(_) => super::config::ElementBehavior::Parse,
97 super::config::ElementBehavior::FlatMap(_) => super::config::ElementBehavior::Parse,
98 };
99 move |input: &'a str| {
100 let inner1 = |s: &'a str| inner.parse(s);
101 conditional(behavior.clone(), vec![()], inner1).parse(input)
102 }
103}
104
105pub(crate) fn conditional_inline_unit<'a, P>(
106 behavior: crate::parser::config::ElementBehavior<Inline>,
107 mut inner: P,
108) -> impl Parser<&'a str, Output = Vec<()>, Error = nom::error::Error<&'a str>>
109where
110 P: Parser<&'a str, Output = (), Error = nom::error::Error<&'a str>>,
111{
112 let behavior: crate::parser::config::ElementBehavior<()> = match behavior {
113 super::config::ElementBehavior::Parse => super::config::ElementBehavior::Parse,
114 super::config::ElementBehavior::Ignore => super::config::ElementBehavior::Ignore,
115 super::config::ElementBehavior::Skip => super::config::ElementBehavior::Skip,
116 super::config::ElementBehavior::Map(_) => super::config::ElementBehavior::Parse,
117 super::config::ElementBehavior::FlatMap(_) => super::config::ElementBehavior::Parse,
118 };
119 move |input: &'a str| {
120 let inner1 = |s: &'a str| inner.parse(s);
121 conditional(behavior.clone(), vec![()], inner1).parse(input)
122 }
123}
124
125pub(crate) fn conditional_block<'a, P>(
126 behavior: crate::parser::config::ElementBehavior<Block>,
127 mut inner: P,
128) -> impl Parser<&'a str, Output = Vec<Block>, Error = nom::error::Error<&'a str>>
129where
130 P: Parser<&'a str, Output = Block, Error = nom::error::Error<&'a str>>,
131{
132 move |input: &'a str| {
133 let inner1 = |s: &'a str| inner.parse(s);
134 conditional(behavior.clone(), vec![Block::Empty], inner1).parse(input)
135 }
136}
137
138pub(crate) fn conditional_inline<'a, P>(
139 behavior: crate::parser::config::ElementBehavior<Inline>,
140 mut inner: P,
141) -> impl Parser<&'a str, Output = Vec<Inline>, Error = nom::error::Error<&'a str>>
142where
143 P: Parser<&'a str, Output = Inline, Error = nom::error::Error<&'a str>>,
144{
145 move |input: &'a str| {
146 let inner1 = |s: &'a str| inner.parse(s);
147 conditional(behavior.clone(), vec![Inline::Empty], inner1).parse(input)
148 }
149}
150
151pub(crate) fn conditional_block_vec<'a, P>(
152 behavior: crate::parser::config::ElementBehavior<Block>,
153 mut inner: P,
154) -> impl Parser<&'a str, Output = Vec<Block>, Error = nom::error::Error<&'a str>>
155where
156 P: Parser<&'a str, Output = Vec<Block>, Error = nom::error::Error<&'a str>>,
157{
158 move |input: &'a str| {
159 let mut inner1 = |s: &'a str| inner.parse(s);
160 match &behavior {
161 crate::parser::config::ElementBehavior::Ignore => fail().parse(input),
162 crate::parser::config::ElementBehavior::Parse => inner1(input),
163 crate::parser::config::ElementBehavior::Skip => {
164 let (remaining, _) = inner1(input)?;
165 Ok((remaining, vec![Block::Empty]))
166 }
167 crate::parser::config::ElementBehavior::Map(_) => {
168 inner1(input)
170 }
171 crate::parser::config::ElementBehavior::FlatMap(_) => {
172 inner1(input)
174 }
175 }
176 }
177}