1#![doc = include_str!("../readme.md")]
2#![cfg_attr(not(test), no_std)]
3#![feature(trait_alias)]
4#![feature(try_trait_v2)]
5#![warn(missing_docs)]
6#![deny(clippy::default_numeric_fallback)]
7
8use core::{
13 fmt::{
14 Debug,
15 Display,
16 },
17 ops::{
18 BitOr,
19 FromResidual,
20 Try,
21 },
22};
23
24use binator_core::{
25 Contexting,
26 Parse,
27 Parsed,
28 Streaming,
29};
30
31mod span;
32pub use span::*;
33mod opt;
34pub use opt::*;
35mod and;
36pub use and::*;
37mod and_then;
38pub use and_then::*;
39mod and_drop;
40pub use and_drop::*;
41mod drop_and;
42pub use drop_and::*;
43mod or;
44pub use or::*;
45mod not;
46pub use not::*;
47mod peek;
48pub use peek::*;
49mod map;
50pub use map::*;
51mod to;
52pub use to::*;
53mod try_map;
54pub use try_map::*;
55mod drop;
56pub use drop::*;
57mod filter;
63pub use filter::*;
64mod filter_map;
65pub use filter_map::*;
66
67mod fold_bounds;
68pub use fold_bounds::*;
69mod try_fold_bounds;
70pub use try_fold_bounds::*;
71mod try_fold_iter;
72pub use try_fold_iter::*;
73mod fold_until;
74pub use fold_until::*;
75mod try_fold_until;
76pub use try_fold_until::*;
77mod fill;
78pub use fill::*;
79
80mod enumerate;
81pub use enumerate::*;
82mod limit;
83pub use limit::*;
84
85mod add_atom;
86pub use add_atom::*;
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub enum UtilsAtom<Stream> {
91 MinNotReach {
93 i: usize,
95 min: usize,
97 },
98 UntilNotReach,
100 Max(usize),
104 Filter,
106 Diff {
111 stream: Stream,
113 stream_success: Stream,
115 },
116}
117
118impl<Stream> Display for UtilsAtom<Stream> {
119 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
120 match self {
121 UtilsAtom::MinNotReach { i, min } => write!(f, "MinNotReach: {} < {}", i, min),
122 UtilsAtom::UntilNotReach => write!(f, "UntilNotReach"),
123 UtilsAtom::Max(n) => write!(f, "Max {}", n),
125 UtilsAtom::Filter { .. } => write!(f, "Filter"),
126 UtilsAtom::Diff { .. } => write!(f, "Diff"),
127 }
128 }
129}
130
131pub trait Utils<Stream, Context>: Sized + Parse<Stream, Context>
140where
141 Stream: Streaming,
142{
143 fn and_then<OtherParser, F>(self, f: F) -> AndThen<Self, F>
148 where
149 OtherParser: Parse<Stream, Context>,
150 F: Fn(Self::Token) -> OtherParser,
151 {
152 and_then(self, f)
153 }
154
155 fn and<OtherParser, OtherToken>(self, other: OtherParser) -> And<Self, OtherParser>
159 where
160 OtherParser: Parse<Stream, Context, Token = OtherToken>,
161 {
162 and(self, other)
163 }
164
165 fn and_drop<OtherParser, OtherToken>(self, other: OtherParser) -> AndDrop<Self, OtherParser>
168 where
169 OtherParser: Parse<Stream, Context, Token = OtherToken>,
170 {
171 and_drop(self, other)
172 }
173
174 fn drop_and<OtherParser, OtherToken>(self, other: OtherParser) -> DropAnd<Self, OtherParser>
177 where
178 OtherParser: Parse<Stream, Context, Token = OtherToken>,
179 {
180 drop_and(self, other)
181 }
182
183 fn drop(self) -> Drop<Self> {
186 drop(self)
187 }
188
189 fn fill<const N: usize>(self) -> Fill<Self, N>
192 where
193 Context: Contexting<UtilsAtom<Stream>>,
194 {
195 fill(self)
196 }
197
198 fn try_fold_iter<IntoIter, Init, Acc, Ret, F>(
205 self, iter: IntoIter, init: Init, f: F,
206 ) -> TryFoldIter<Self, IntoIter, Init, F>
207 where
208 Context: Contexting<UtilsAtom<Stream>>,
209 IntoIter: IntoIterator + Clone,
210 Init: Fn() -> Ret,
211 F: Fn(Acc, Self::Token, IntoIter::Item) -> Ret,
212 Ret: Try<Output = Acc>,
213 Parsed<Acc, Stream, Context>: FromResidual<Ret::Residual>,
214 {
215 try_fold_iter(self, iter, init, f)
216 }
217
218 fn fold_until<TokenUntil, Acc, Until, Init, F>(
225 self, until: Until, init: Init, f: F,
226 ) -> FoldUntil<Self, Until, Init, F>
227 where
228 Context: Contexting<UtilsAtom<Stream>>,
229 Until: Parse<Stream, Context, Token = TokenUntil>,
230 Init: FnMut() -> Acc,
231 F: FnMut(Acc, Self::Token) -> Acc,
232 {
233 fold_until(self, until, init, f)
234 }
235
236 fn try_fold_until<TokenUntil, Acc, Parser, Until, Init, Ret, F>(
238 self, until: Until, init: Init, f: F,
239 ) -> TryFoldUntil<Self, Until, Init, F>
240 where
241 Context: Contexting<UtilsAtom<Stream>>,
242 Until: Parse<Stream, Context, Token = TokenUntil>,
243 Init: Fn() -> Ret,
244 F: Fn(Acc, Self::Token) -> Ret,
245 Ret: Try<Output = Acc>,
246 Parsed<(Acc, Until::Token), Stream, Context>: FromResidual<Ret::Residual>,
247 {
248 try_fold_until(self, until, init, f)
249 }
250
251 fn fold_bounds<Bounds, Acc, Init, F>(
271 self, bounds: Bounds, init: Init, f: F,
272 ) -> FoldBounds<Self, Bounds, Init, F>
273 where
274 Context: Contexting<UtilsAtom<Stream>>,
275 Init: FnMut() -> Acc,
276 F: FnMut(Acc, Self::Token) -> Acc,
277 Bounds: FoldBoundsParse,
278 Acc: Debug,
279 {
280 fold_bounds(self, bounds, init, f)
281 }
282
283 fn try_fold_bounds<Bounds, Acc, Init, Ret, F>(
285 self, bounds: Bounds, init: Init, f: F,
286 ) -> TryFoldBounds<Self, Bounds, Init, F>
287 where
288 Context: Contexting<UtilsAtom<Stream>>,
289 Init: Fn() -> Ret,
290 F: Fn(Acc, Self::Token) -> Ret,
291 Ret: Try<Output = Acc>,
292 Parsed<Acc, Stream, Context>: FromResidual<Ret::Residual>,
293 Bounds: TryFoldBoundsParse,
294 Acc: Debug,
295 {
296 try_fold_bounds(self, bounds, init, f)
297 }
298
299 fn add_atom<F, Atom>(self, f: F) -> AddAtom<Self, F>
302 where
303 F: Fn() -> Atom,
304 Context: Contexting<Atom>,
305 {
306 add_atom(self, f)
307 }
308
309 fn map<F, OtherToken>(self, f: F) -> Map<Self, F>
313 where
314 F: Fn(Self::Token) -> OtherToken,
315 {
316 map(self, f)
317 }
318
319 fn filter<F>(self, f: F) -> Filter<Self, F>
321 where
322 F: Fn(&Self::Token) -> bool,
323 Context: Contexting<UtilsAtom<Stream>>,
324 {
325 filter(self, f)
326 }
327
328 fn filter_map<F, OtherToken>(self, f: F) -> FilterMap<Self, F>
331 where
332 F: Fn(Self::Token) -> Option<OtherToken>,
333 OtherToken: Clone,
334 Context: Contexting<UtilsAtom<Stream>>,
335 {
336 filter_map(self, f)
337 }
338
339 fn to<OtherToken>(self, t: OtherToken) -> To<Self, OtherToken>
344 where
345 OtherToken: Clone,
346 {
347 to(self, t)
348 }
349
350 fn not(self) -> Not<Self>
354 where
355 Stream: Clone,
356 Context: Contexting<NotAtom<Self::Token, Stream>>,
357 {
358 not(self)
359 }
360
361 fn opt(self) -> Optional<Self>
365 where
366 Stream: Clone,
367 {
368 opt(self)
369 }
370
371 fn enumerate(self) -> Enumerate<Self> {
374 enumerate(self)
375 }
376
377 fn limit(self, n: usize) -> Limit<Self>
382 where
383 Context: Contexting<UtilsAtom<Stream>>,
384 {
385 limit(self, n)
386 }
387
388 fn or<OtherParser>(self, b: OtherParser) -> Or<Self, OtherParser>
392 where
393 Stream: Clone,
394 OtherParser: Parse<Stream, Context>,
395 Context: BitOr,
396 {
397 or(self, b)
398 }
399
400 fn peek(self) -> Peek<Self>
404 where
405 Stream: Clone,
406 {
407 peek(self)
408 }
409
410 fn span(self) -> Span<Self>
416 where
417 Context: Contexting<UtilsAtom<Stream>>,
418 {
419 span(self)
420 }
421
422 fn try_map<OtherToken, F, Ret>(self, f: F) -> TryMap<Self, F>
424 where
425 F: Fn(Self::Token) -> Ret,
426 Ret: Try<Output = OtherToken>,
427 Parsed<OtherToken, Stream, Context>: FromResidual<Ret::Residual>,
428 {
429 try_map(self, f)
430 }
431}
432
433impl<T, Stream, Context> Utils<Stream, Context> for T
434where
435 Stream: Streaming,
436 Self: Parse<Stream, Context>,
437{
438}