1pub use rustidy_macros::ParseRecursive;
5
6use {
8 crate::{self as rustidy_parse, PeekState},
9 super::{ParsableFrom, Parse, ParseError, Parser, ParserError, ParserTag},
10 core::{marker::PhantomData, mem},
11 either::Either,
12};
13
14pub trait ParsableRecursive<R> {
16 type Prefix: Parse;
18
19 type Base: Parse;
21
22 type Suffix: Parse;
24
25 type Infix: Parse;
27
28 fn join_prefix(prefix: Self::Prefix, root: R, parser: &mut Parser) -> Self;
30
31 fn from_base(base: Self::Base, parser: &mut Parser) -> Self;
33
34 fn join_suffix(root: R, suffix: Self::Suffix, parser: &mut Parser) -> Self;
36
37 fn join_infix(lhs: R, infix: Self::Infix, rhs: R, parser: &mut Parser) -> Self;
39}
40
41pub trait FromRecursiveRoot<R> {
42 fn from_recursive_root(root: R, parser: &mut Parser) -> Self;
43}
44
45impl<R, T> FromRecursiveRoot<R> for T
46where
47 T: From<R>, {
48 fn from_recursive_root(root: R, _parser: &mut Parser) -> T {
49 T::from(root)
50 }
51}
52
53pub trait TryFromRecursiveRoot<R>: Sized {
54 fn try_from_recursive_root(root: R, parser: &mut Parser) -> Option<Self>;
55}
56
57impl<R> TryFromRecursiveRoot<R> for R {
58 fn try_from_recursive_root(root: R, _parser: &mut Parser) -> Option<Self> {
59 Some(root)
60 }
61}
62
63pub trait IntoRecursiveRoot<R> {
64 fn into_recursive_root(self, parser: &mut Parser) -> R;
65}
66
67
68impl<R> IntoRecursiveRoot<R> for R {
69 fn into_recursive_root(self, _parser: &mut Parser) -> Self {
70 self
71 }
72}
73
74
75impl<R> ParsableRecursive<R> for ! {
76 type Base = !;
77 type Infix = !;
78 type Prefix = !;
79 type Suffix = !;
80
81 fn join_prefix(prefix: Self::Prefix, _: R, _parser: &mut Parser) -> Self {
82 prefix
83 }
84
85 fn from_base(base: Self::Base, _parser: &mut Parser) -> Self {
86 base
87 }
88
89 fn join_suffix(_: R, suffix: Self::Suffix, _parser: &mut Parser) -> Self {
90 suffix
91 }
92
93 fn join_infix(_: R, infix: Self::Infix, _: R, _parser: &mut Parser) -> Self {
94 infix
95 }
96}
97
98#[derive(derive_more::Debug)]
100pub struct RecursiveWrapper<T, R>(pub T, pub PhantomData<R>);
101
102impl<T, R> ParsableFrom<RecursiveWrapper<T, R>> for T {
103 fn from_parsable(wrapper: RecursiveWrapper<T, R>) -> Self {
104 wrapper.0
105 }
106}
107
108impl<T, R> crate::Parse for RecursiveWrapper<T, R>
111where
112 T: TryFromRecursiveRoot<R>,
113 R: ParsableRecursive<R>, {
114 type Error = RecursiveWrapperError<R>;
115
116 fn parse_from(parser: &mut Parser) -> Result<Self, Self::Error> {
118 let convert_inner = |parser: &mut Parser, inner: RecursiveWrapperInnerPart<R>| {
119 let mut base = R::from_base(inner.base, parser);
120 for prefix in inner.prefixes.into_iter().rev() {
121 base = R::join_prefix(prefix, base, parser);
122 }
123 for suffix in inner.suffixes {
124 base = R::join_suffix(base, suffix, parser);
125 }
126
127 base
128 };
129
130 let inner = self::parse(parser)?;
131
132 let mut base = convert_inner(parser, inner.first);
133 for (infix, rhs) in inner.rest {
134 base = R::join_infix(base, infix, convert_inner(parser, rhs), parser);
135 }
136
137 let base = T::try_from_recursive_root(base, parser)
138 .ok_or(Self::Error::FromRoot)?;
139
140 Ok(Self(base, PhantomData))
141 }
142}
143
144#[derive(derive_more::Debug, ParseError)]
145pub enum RecursiveWrapperError<R: ParsableRecursive<R>> {
146 #[parse_error(transparent)]
147 Prefix(ParserError<R::Prefix>),
148
149 #[parse_error(transparent)]
150 Suffix(ParserError<R::Suffix>),
151
152 #[parse_error(transparent)]
153 Infix(ParserError<R::Infix>),
154
155 #[parse_error(transparent)]
156 Base(ParserError<R::Base>),
157
158 #[parse_error(transparent)]
159 #[doc(hidden)]
160 BracesOpen(ParserError<ParseBracesOpen>),
161
162 #[parse_error(fmt = "Expected a prefix or base")]
163 #[parse_error(multiple)]
164 PrefixOrBase {
165 prefix: ParserError<R::Prefix>,
166 base: ParserError<R::Base>,
167 },
168
169 #[parse_error(fmt = "Expected a suffix or infix")]
170 #[parse_error(multiple)]
171 SuffixOrInfix {
172 suffix: ParserError<R::Suffix>,
173 infix: ParserError<R::Infix>,
174 },
175
176 #[parse_error(fmt = "None matched")]
177 #[parse_error(multiple)]
178 None {
179 prefix: ParserError<R::Prefix>,
180 suffix: ParserError<R::Suffix>,
181 infix: ParserError<R::Infix>,
182 base: ParserError<R::Base>,
183 },
184
185 #[parse_error(fmt = "Unable to convert from root")]
186 FromRoot,
187}
188
189#[derive(derive_more::Debug)]
190struct RecursiveWrapperInner<R: ParsableRecursive<R>> {
191 first: RecursiveWrapperInnerPart<R>,
192 rest: Vec<(R::Infix, RecursiveWrapperInnerPart<R>)>,
193}
194
195#[derive(derive_more::Debug)]
196struct RecursiveWrapperInnerPart<R: ParsableRecursive<R>> {
197 prefixes: Vec<R::Prefix>,
198 base: R::Base,
199 suffixes: Vec<R::Suffix>,
200}
201
202fn parse<R: ParsableRecursive<R>>(parser: &mut Parser) -> Result<RecursiveWrapperInner<R>, RecursiveWrapperError<R>> {
203 #[expect(clippy::type_complexity, reason = "TODO")]
208 fn peek<T: Parse>(parser: &mut Parser, tags: &[ParserTag],) -> Result<Result<(T, PeekState), ParserError<T>>, ParserError<T>> {
209 parser
210 .with_tags(tags.iter().copied(), Parser::peek::<T>)
211 }
212 let tags = parser.tags().collect::<Vec<_>>();
213
214 let mut inners = vec![];
215
216 let mut cur_prefixes = vec![];
217 let last_inner = loop {
218 let prefix = peek::<R::Prefix>(parser, &tags)
219 .map_err(RecursiveWrapperError::Prefix)?;
220 let base = peek::<R::Base>(parser, &tags)
221 .map_err(RecursiveWrapperError::Base)?;
222
223 let parsed = match (prefix, base) {
224 (Ok((prefix, prefix_state)), Ok((base, base_state))) => {
225 parser.set_peeked(base_state);
226 match peek::<R::Base>(parser, &tags)
227 .map_err(RecursiveWrapperError::Base)?
228 .is_ok() {
229 true => Either::Left((prefix, prefix_state)),
230 false => Either::Right((base, None)),
232 }
233 },
234 (Ok((prefix, prefix_state)), Err(_)) => Either::Left((prefix, prefix_state)),
235 (Err(_), Ok((base, base_state))) => Either::Right((base, Some(base_state))),
236 (Err(prefix), Err(base)) => return Err(
237 RecursiveWrapperError::PrefixOrBase { prefix, base }
238 ),
239 };
240
241 match parsed {
242 Either::Left((prefix, prefix_state)) => {
243 parser.set_peeked(prefix_state);
244 cur_prefixes.push(prefix);
245 },
246 Either::Right((base, base_state)) => {
247 if let Some(state) = base_state {
248 parser.set_peeked(state);
249 }
250
251 let mut cur_suffixes = vec![];
252 let infix = loop {
253 let suffix = peek::<R::Suffix>(parser, &tags)
254 .map_err(RecursiveWrapperError::Suffix)?;
255 let infix = peek::<R::Infix>(parser, &tags)
256 .map_err(RecursiveWrapperError::Infix)?;
257
258 let parsed = match (suffix, infix) {
259 (Ok((suffix, suffix_state)), Ok((infix, infix_state))) => 'parsed: {
260 parser.set_peeked(infix_state);
261 if tags
271 .contains(&ParserTag::SkipOptionalTrailingBlockExpression) && peek::<ParseBracesOpen>(parser, &tags)
272 .map_err(RecursiveWrapperError::BracesOpen)?
273 .is_ok() {
274 break 'parsed Either::Left((suffix, suffix_state));
276 }
277
278 match peek::<R::Prefix>(parser, &tags)
279 .map_err(RecursiveWrapperError::Prefix)?
280 .is_ok() || peek::<R::Base>(parser, &tags)
281 .map_err(RecursiveWrapperError::Base)?
282 .is_ok() {
283 true => Either::Right((infix, None)),
285 false => Either::Left((suffix, suffix_state)),
286 }
287 },
288 (Ok((suffix, suffix_state)), Err(_)) => Either::Left((suffix, suffix_state)),
289 (Err(_), Ok((infix, infix_state))) => Either::Right((infix, Some(infix_state))),
290 (Err(_), Err(_)) => break None,
291 };
292
293 match parsed {
294 Either::Left((suffix, suffix_state)) => {
295 parser.set_peeked(suffix_state);
296 cur_suffixes.push(suffix);
297 },
298 Either::Right((infix, infix_state)) => {
299 if let Some(state) = infix_state {
300 parser.set_peeked(state);
301 }
302 break Some(infix);
303 },
304 }
305 };
306
307 let inner = RecursiveWrapperInnerPart {
308 prefixes: mem::take(&mut cur_prefixes),
309 base,
310 suffixes: cur_suffixes,
311 };
312
313 match infix {
314 Some(infix) => inners.push((inner, infix)),
315 None => break inner,
316 }
317 },
318 }
319 };
320
321 let mut inners = inners.into_iter();
322 let (first, rest) = match inners.next() {
323 Some((first_inner, mut infix)) => {
324 let mut rest = vec![];
325 for (inner, next_infix) in inners {
326 rest.push((infix, inner));
327 infix = next_infix;
328 }
329 rest.push((infix, last_inner));
330
331 (first_inner, rest)
332 },
333 None => (last_inner, vec![]),
334 };
335
336 Ok(RecursiveWrapperInner { first, rest })
337}
338
339#[doc(hidden)]
342pub struct ParseBracesOpen;
343
344impl Parse for ParseBracesOpen {
345 type Error = ();
346
347 fn parse_from(parser: &mut Parser) -> Result<Self, Self::Error> {
348 if parser.has_tag(ParserTag::SkipDelimiters) {
349 return Err(());
350 }
351
352 parser.try_update_with(|s| {
353 *s = s.trim_start();
355 match s.strip_prefix('{') {
356 Some(rest) => {
357 *s = rest;
358 Ok(())
359 },
360 None => Err(()),
361 }
362 }).map(|_| Self)
363 }
364}