1#![allow(non_camel_case_types)]
4
5use core::marker::PhantomData;
6
7use crate::{internal_prelude::*, Rule};
8
9use super::{
10 CompoundToken, DelimitedList, Discard, DualParse, Empty, Ignore, NotEmpty, NotParse,
11 TransformList,
12};
13
14pub trait TransformInto<Out> {
16 type Input;
18 fn transform(input: Self::Input) -> Out;
20}
21
22#[non_exhaustive]
24pub struct identity {}
25
26impl<T> TransformInto<T> for identity {
27 type Input = T;
28
29 fn transform(input: Self::Input) -> T {
30 input
31 }
32}
33
34pub struct compose<A, B> {
36 _a: A,
37 _b: B,
38}
39
40impl<A, B, Out> TransformInto<Out> for compose<A, B>
41where
42 A: TransformInto<B::Input>,
43 B: TransformInto<Out>,
44{
45 type Input = A::Input;
46 fn transform(input: Self::Input) -> Out {
47 B::transform(A::transform(input))
48 }
49}
50
51pub struct delimited<Delim: Rule, const TRAIL: bool = true> {
55 _delim: PhantomData<Delim>,
56}
57
58impl<T: Rule, Delim: Rule, const TRAIL: bool> TransformInto<Vec<T>> for delimited<Delim, TRAIL> {
59 type Input = DelimitedList<T, Delim, TRAIL>;
60
61 fn transform(input: Self::Input) -> Vec<T> {
62 input.items
63 }
64}
65
66impl<T: Rule, X: TransformInto<T>, Delim: Rule, const TRAIL: bool>
67 TransformInto<TransformList<T, X, Delim>> for delimited<Delim, TRAIL>
68{
69 type Input = TransformList<T, X, Delim, TRAIL>;
70
71 fn transform(input: Self::Input) -> TransformList<T, X, Delim> {
72 TransformList::new(input.items)
73 }
74}
75
76pub struct ignore_before<S> {
79 _space: PhantomData<S>,
80}
81
82impl<T: Rule, S: Rule> TransformInto<T> for ignore_before<S> {
83 type Input = (Ignore<S>, T);
84
85 fn transform((_, out): Self::Input) -> T {
86 out
87 }
88}
89
90pub struct ignore_after<S> {
93 _space: PhantomData<S>,
94}
95
96impl<T: Rule, S: Rule> TransformInto<T> for ignore_after<S> {
97 type Input = (T, Ignore<S>);
98
99 fn transform((out, _): Self::Input) -> T {
100 out
101 }
102}
103
104pub type ignore_around<S1, S2 = S1> = compose<ignore_before<S1>, ignore_after<S2>>;
107
108pub struct discard_before<S> {
111 _space: PhantomData<S>,
112}
113
114impl<T: Rule, S: Rule> TransformInto<T> for discard_before<S> {
115 type Input = (Discard<S>, T);
116
117 fn transform((_, out): Self::Input) -> T {
118 out
119 }
120}
121
122pub struct discard_after<S> {
125 _space: PhantomData<S>,
126}
127
128impl<T: Rule, S: Rule> TransformInto<T> for discard_after<S> {
129 type Input = (T, Discard<S>);
130
131 fn transform((out, _): Self::Input) -> T {
132 out
133 }
134}
135
136pub type discard_around<S1, S2 = S1> = compose<discard_before<S1>, discard_after<S2>>;
139
140pub struct map<X> {
143 _x: PhantomData<X>,
144}
145
146impl<In: Rule, Out, X: TransformInto<Out, Input = In>> TransformInto<Option<Out>> for map<X> {
147 type Input = Option<In>;
148
149 fn transform(input: Self::Input) -> Option<Out> {
150 input.map(X::transform)
151 }
152}
153
154pub struct for_each<X> {
157 _x: PhantomData<X>,
158}
159
160impl<In: Rule, Out, X: TransformInto<Out, Input = In>> TransformInto<Vec<Out>> for for_each<X> {
161 type Input = TransformList<Out, X>;
162
163 fn transform(input: Self::Input) -> Vec<Out> {
164 input.items
165 }
166}
167
168impl<
169 In: Rule,
170 Out,
171 In1: Rule,
172 X: TransformInto<In1, Input = In>,
173 X1: TransformInto<Out, Input = In1>,
174 Delim: Rule,
175 const TRAIL: bool,
176 const PREFER_SHORT: bool,
177 > TransformInto<TransformList<Out, X1, Delim, TRAIL, PREFER_SHORT>> for for_each<X>
178{
179 type Input = TransformList<Out, compose<X, X1>, Delim, TRAIL, PREFER_SHORT>;
180
181 fn transform(input: Self::Input) -> TransformList<Out, X1, Delim, TRAIL, PREFER_SHORT> {
182 TransformList::new(input.items)
183 }
184}
185
186#[non_exhaustive]
188pub struct prefer_short<const PREFER_SHORT: bool = true> {}
189
190impl<T: Rule, const PREFER_SHORT: bool> TransformInto<Vec<T>> for prefer_short<PREFER_SHORT> {
191 type Input = TransformList<T, identity, Empty, false, PREFER_SHORT>;
192
193 fn transform(input: Self::Input) -> Vec<T> {
194 input.items
195 }
196}
197
198impl<
199 T: Rule,
200 X: TransformInto<T>,
201 Delim: Rule,
202 const TRAIL: bool,
203 const PREFER_SHORT: bool,
204 const PREFER_SHORT1: bool,
205 > TransformInto<TransformList<T, X, Delim, TRAIL, PREFER_SHORT1>>
206 for prefer_short<PREFER_SHORT>
207{
208 type Input = TransformList<T, X, Delim, TRAIL, PREFER_SHORT>;
209
210 fn transform(input: Self::Input) -> TransformList<T, X, Delim, TRAIL, PREFER_SHORT1> {
211 TransformList::new(input.items)
212 }
213}
214
215#[non_exhaustive]
217pub struct compound_token {}
218
219impl<T: Rule> TransformInto<T> for compound_token {
220 type Input = CompoundToken<T>;
221
222 fn transform(input: Self::Input) -> T {
223 input.value
224 }
225}
226
227pub struct parse_as<Outer> {
233 _outer: PhantomData<Outer>,
234}
235
236impl<Outer: Rule, Inner: Rule> TransformInto<Inner> for parse_as<Outer> {
237 type Input = DualParse<Outer, Inner>;
238
239 fn transform(input: Self::Input) -> Inner {
240 input.inner
241 }
242}
243
244pub struct not<Invalid> {
246 _invalid: PhantomData<Invalid>,
247}
248
249impl<Invalid: Rule, Valid: Rule> TransformInto<Valid> for not<Invalid> {
250 type Input = NotParse<Invalid, Valid>;
251
252 fn transform(input: Self::Input) -> Valid {
253 input.value
254 }
255}
256
257pub struct not_empty;
258
259impl<T> TransformInto<T> for not_empty {
260 type Input = NotEmpty<T>;
261
262 fn transform(input: Self::Input) -> T {
263 input.value
264 }
265}