1use crate::{
3 args::State,
4 buffer::MetaInfo,
5 error::{Message, MissingItem},
6 Doc, Error, Meta, Parser,
7};
8use std::marker::PhantomData;
9
10pub struct ParseFallbackWith<T, P, F, E> {
13 pub(crate) inner: P,
14 pub(crate) inner_res: PhantomData<T>,
15 pub(crate) fallback: F,
16 pub(crate) value_str: String,
17 pub(crate) err: PhantomData<E>,
18}
19
20impl<T, P, F, E> Parser<T> for ParseFallbackWith<T, P, F, E>
21where
22 P: Parser<T>,
23 F: Fn() -> Result<T, E>,
24 E: ToString,
25{
26 fn eval(&self, args: &mut State) -> Result<T, Error> {
27 let mut clone = args.clone();
28 match self.inner.eval(&mut clone) {
29 Ok(ok) => {
30 std::mem::swap(args, &mut clone);
31 Ok(ok)
32 }
33 Err(Error(e)) => {
34 #[cfg(feature = "autocomplete")]
35 args.swap_comps(&mut clone);
36 if e.can_catch() {
37 match (self.fallback)() {
38 Ok(ok) => Ok(ok),
39 Err(e) => Err(Error(Message::PureFailed(e.to_string()))),
40 }
41 } else {
42 Err(Error(e))
43 }
44 }
45 }
46 }
47
48 fn meta(&self) -> Meta {
49 let m = Meta::Optional(Box::new(self.inner.meta()));
50 if self.value_str.is_empty() {
51 m
52 } else {
53 let buf = Doc::from(self.value_str.as_str());
54 Meta::Suffix(Box::new(m), Box::new(buf))
55 }
56 }
57}
58
59pub struct ParseGroupHelp<P> {
61 pub(crate) inner: P,
62 pub(crate) message: Doc,
63}
64
65impl<T, P> Parser<T> for ParseGroupHelp<P>
66where
67 P: Parser<T>,
68{
69 fn eval(&self, args: &mut State) -> Result<T, Error> {
70 #[cfg(feature = "autocomplete")]
71 let mut comp_items = Vec::new();
72 #[cfg(feature = "autocomplete")]
73 args.swap_comps_with(&mut comp_items);
74
75 #[allow(clippy::let_and_return)]
76 let res = self.inner.eval(args);
77
78 #[cfg(feature = "autocomplete")]
79 args.swap_comps_with(&mut comp_items);
80 #[cfg(feature = "autocomplete")]
81 args.push_with_group(&self.message.to_completion(), &mut comp_items);
82
83 res
84 }
85
86 fn meta(&self) -> Meta {
87 let meta = Box::new(self.inner.meta());
88 Meta::Subsection(meta, Box::new(self.message.clone()))
89 }
90}
91
92pub struct ParseWithGroupHelp<P, F> {
94 pub(crate) inner: P,
95 pub(crate) f: F,
96}
97
98impl<T, P, F> Parser<T> for ParseWithGroupHelp<P, F>
99where
100 P: Parser<T>,
101 F: Fn(MetaInfo) -> Doc,
102{
103 fn eval(&self, args: &mut State) -> Result<T, Error> {
104 self.inner.eval(args)
105 }
106
107 fn meta(&self) -> Meta {
108 let meta = self.inner.meta();
109 let buf = (self.f)(MetaInfo(&meta));
110
111 Meta::Subsection(Box::new(meta), Box::new(buf))
112 }
113}
114
115pub struct ParseSome<P> {
119 pub(crate) inner: P,
120 pub(crate) message: &'static str,
121 pub(crate) catch: bool,
122}
123
124impl<P> ParseSome<P> {
125 #[must_use]
126 #[cfg_attr(not(doctest), doc = include_str!("docs2/some_catch.md"))]
135 pub fn catch(mut self) -> Self {
136 self.catch = true;
137 self
138 }
139}
140
141impl<T, P> Parser<Vec<T>> for ParseSome<P>
142where
143 P: Parser<T>,
144{
145 fn eval(&self, args: &mut State) -> Result<Vec<T>, Error> {
146 let mut res = Vec::new();
147 let mut len = usize::MAX;
148
149 while let Some(val) = parse_option(&self.inner, &mut len, args, self.catch)? {
150 res.push(val);
151 }
152
153 if res.is_empty() {
154 Err(Error(Message::ParseSome(self.message)))
155 } else {
156 Ok(res)
157 }
158 }
159
160 fn meta(&self) -> Meta {
161 Meta::Many(Box::new(Meta::Required(Box::new(self.inner.meta()))))
162 }
163}
164
165pub struct ParseCollect<P, C, T> {
169 pub(crate) inner: P,
170 pub(crate) catch: bool,
171 pub(crate) ctx: PhantomData<(C, T)>,
172}
173
174impl<T, C, P> ParseCollect<P, C, T> {
175 #[must_use]
176 #[cfg_attr(not(doctest), doc = include_str!("docs2/some_catch.md"))]
185 pub fn catch(mut self) -> Self {
186 self.catch = true;
187 self
188 }
189}
190
191impl<T, C, P> Parser<C> for ParseCollect<P, C, T>
192where
193 P: Parser<T>,
194 C: FromIterator<T>,
195{
196 fn eval(&self, args: &mut State) -> Result<C, Error> {
197 let mut len = usize::MAX;
198 std::iter::from_fn(|| parse_option(&self.inner, &mut len, args, self.catch).transpose())
199 .collect::<Result<C, Error>>()
200 }
201
202 fn meta(&self) -> Meta {
203 Meta::Many(Box::new(Meta::Required(Box::new(self.inner.meta()))))
204 }
205}
206
207pub struct ParseHide<P> {
210 pub(crate) inner: P,
211}
212
213impl<T, P> Parser<T> for ParseHide<P>
214where
215 P: Parser<T>,
216{
217 fn eval(&self, args: &mut State) -> Result<T, Error> {
218 #[cfg(feature = "autocomplete")]
219 let mut comps = Vec::new();
220
221 #[cfg(feature = "autocomplete")]
222 args.swap_comps_with(&mut comps);
223
224 #[allow(clippy::let_and_return)]
225 let res = self.inner.eval(args);
226
227 #[cfg(feature = "autocomplete")]
228 args.swap_comps_with(&mut comps);
229 if let Err(Error(Message::Missing(_))) = res {
230 Err(Error(Message::Missing(Vec::new())))
231 } else {
232 res
233 }
234 }
235
236 fn meta(&self) -> Meta {
237 Meta::Skip
238 }
239}
240
241pub struct ParseUsage<P> {
245 pub(crate) inner: P,
246 pub(crate) usage: Doc,
247}
248impl<T, P> Parser<T> for ParseUsage<P>
249where
250 P: Parser<T>,
251{
252 fn eval(&self, args: &mut State) -> Result<T, Error> {
253 self.inner.eval(args)
254 }
255
256 fn meta(&self) -> Meta {
257 Meta::CustomUsage(Box::new(self.inner.meta()), Box::new(self.usage.clone()))
258 }
259}
260
261pub struct ParseOrElse<T> {
264 pub(crate) this: Box<dyn Parser<T>>,
265 pub(crate) that: Box<dyn Parser<T>>,
266}
267
268impl<T> Parser<T> for ParseOrElse<T> {
269 fn eval(&self, args: &mut State) -> Result<T, Error> {
270 #[cfg(feature = "autocomplete")]
271 let mut comp_items = Vec::new();
272 #[cfg(feature = "autocomplete")]
273 args.swap_comps_with(&mut comp_items);
274
275 let mut args_a = args.clone();
280 let mut args_b = args.clone();
281
282 let (res_a, err_a) = match self.this.eval(&mut args_a) {
287 Ok(ok) => (Some(ok), None),
288 Err(err) => (None, Some(err)),
289 };
290
291 let (res_b, err_b) = match self.that.eval(&mut args_b) {
292 Ok(ok) => (Some(ok), None),
293 Err(err) => (None, Some(err)),
294 };
295
296 if this_or_that_picks_first(
297 err_a,
298 err_b,
299 args,
300 &mut args_a,
301 &mut args_b,
302 #[cfg(feature = "autocomplete")]
303 comp_items,
304 )? {
305 Ok(res_a.unwrap())
306 } else {
307 Ok(res_b.unwrap())
308 }
309 }
310
311 fn meta(&self) -> Meta {
312 self.this.meta().or(self.that.meta())
313 }
314}
315
316fn this_or_that_picks_first(
319 err_a: Option<Error>,
320 err_b: Option<Error>,
321 args: &mut State,
322 args_a: &mut State,
323 args_b: &mut State,
324
325 #[cfg(feature = "autocomplete")] mut comp_stash: Vec<crate::complete_gen::Comp>,
326) -> Result<bool, Error> {
327 match Ord::cmp(&args_a.depth(), &args_b.depth()) {
330 std::cmp::Ordering::Less => {
331 std::mem::swap(args, args_b);
332 #[cfg(feature = "autocomplete")]
333 if let Some(comp) = args.comp_mut() {
334 comp.extend_comps(comp_stash);
335 }
336 return match err_b {
337 Some(err) => Err(err),
338 None => Ok(false),
339 };
340 }
341 std::cmp::Ordering::Equal => {}
342 std::cmp::Ordering::Greater => {
343 std::mem::swap(args, args_a);
344 #[cfg(feature = "autocomplete")]
345 if let Some(comp) = args.comp_mut() {
346 comp.extend_comps(comp_stash);
347 }
348 return match err_a {
349 Some(err) => Err(err),
350 None => Ok(true),
351 };
352 }
353 }
354
355 let no_consume_a = args.len() == args_a.len();
356 let no_consume_b = args.len() == args_b.len();
357 #[allow(clippy::let_and_return)] let res = match (err_a, err_b) {
360 (None, None) => {
361 if no_consume_a && no_consume_b {
362 Ok((true, None))
363 } else {
364 Ok(args_a.pick_winner(args_b))
365 }
366 }
367 (None, Some(e2)) if no_consume_a && e2.0.wrong_input() => Err(e2),
369 (Some(e1), None) if no_consume_b && e1.0.wrong_input() => Err(e1),
370 (Some(e1), Some(e2)) => Err(e1.combine_with(e2)),
371 (a_ok, _) => Ok((a_ok.is_none(), None)),
373 };
374
375 #[cfg(feature = "autocomplete")]
376 {
377 let mut keep_a = true;
378 let mut keep_b = true;
379 if args_a.len() != args_b.len() {
380 if let (Some(_), Some(_)) = (args_a.comp_mut(), args_b.comp_mut()) {
386 'check: for (ix, arg) in args_a.items.iter().enumerate() {
387 if ix + 1 == args_a.items.len() {
395 let os = arg.os_str();
396 if os.is_empty() || os == "-" || os == "--" {
397 break 'check;
398 }
399 }
400 if let (Some(a), Some(b)) = (args_a.present(ix), args_b.present(ix)) {
401 match (a, b) {
402 (false, true) => {
403 keep_b = false;
404 break 'check;
405 }
406 (true, false) => {
407 keep_a = false;
408 break 'check;
409 }
410 _ => {}
411 }
412 }
413 }
414 }
415 }
416
417 if let (Some(a), Some(b)) = (args_a.comp_mut(), args_b.comp_mut()) {
418 if keep_a {
419 comp_stash.extend(a.drain_comps());
420 }
421 if keep_b {
422 comp_stash.extend(b.drain_comps());
423 }
424 }
425 }
426
427 match res {
428 Ok((true, ix)) => {
429 if let Some(win) = ix {
430 args_a.save_conflicts(args_b, win);
431 }
432 std::mem::swap(args, args_a);
433 }
434 Ok((false, ix)) => {
435 if let Some(win) = ix {
436 args_b.save_conflicts(args_a, win);
437 }
438 std::mem::swap(args, args_b);
439 }
440 Err(_) => {}
442 }
443
444 #[cfg(feature = "autocomplete")]
445 if let Some(comp) = args.comp_mut() {
446 comp.extend_comps(comp_stash);
447 }
448
449 Ok(res?.0)
450}
451
452pub struct ParseWith<T, P, F, E, R> {
455 pub(crate) inner: P,
456 pub(crate) inner_res: PhantomData<T>,
457 pub(crate) parse_fn: F,
458 pub(crate) res: PhantomData<R>,
459 pub(crate) err: PhantomData<E>,
460}
461
462impl<T, P, F, E, R> Parser<R> for ParseWith<T, P, F, E, R>
463where
464 P: Parser<T>,
465 F: Fn(T) -> Result<R, E>,
466 E: ToString,
467{
468 fn eval(&self, args: &mut State) -> Result<R, Error> {
469 let t = self.inner.eval(args)?;
470 match (self.parse_fn)(t) {
471 Ok(r) => Ok(r),
472 Err(e) => Err(Error(Message::ParseFailed(args.current, e.to_string()))),
473 }
474 }
475
476 fn meta(&self) -> Meta {
477 self.inner.meta()
478 }
479}
480
481pub struct ParseFallback<P, T> {
484 pub(crate) inner: P,
485 pub(crate) value: T,
486 pub(crate) value_str: String,
487}
488
489impl<P, T> Parser<T> for ParseFallback<P, T>
490where
491 P: Parser<T>,
492 T: Clone,
493{
494 fn eval(&self, args: &mut State) -> Result<T, Error> {
495 let mut clone = args.clone();
496 match self.inner.eval(&mut clone) {
497 Ok(ok) => {
498 std::mem::swap(args, &mut clone);
499 Ok(ok)
500 }
501 Err(Error(e)) => {
502 #[cfg(feature = "autocomplete")]
503 args.swap_comps(&mut clone);
504 if e.can_catch() {
505 Ok(self.value.clone())
506 } else {
507 Err(Error(e))
508 }
509 }
510 }
511 }
512
513 fn meta(&self) -> Meta {
514 let m = Meta::Optional(Box::new(self.inner.meta()));
515 if self.value_str.is_empty() {
516 m
517 } else {
518 let buf = Doc::from(self.value_str.as_str());
519 Meta::Suffix(Box::new(m), Box::new(buf))
520 }
521 }
522}
523
524struct DisplayWith<'a, T, F>(&'a T, F);
527
528impl<'a, T, F: Fn(&'a T, &mut std::fmt::Formatter<'_>) -> std::fmt::Result> std::fmt::Display
529 for DisplayWith<'a, T, F>
530{
531 #[inline(always)]
532 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
533 let Self(value, display) = self;
534 display(value, f)
535 }
536}
537
538impl<P, T: std::fmt::Display> ParseFallback<P, T> {
539 #[cfg_attr(not(doctest), doc = include_str!("docs2/dis_fallback.md"))]
543 #[must_use]
544 pub fn display_fallback(mut self) -> Self {
545 self.value_str = format!("[default: {}]", self.value);
546 self
547 }
548}
549
550impl<P, T: std::fmt::Debug> ParseFallback<P, T> {
551 #[cfg_attr(not(doctest), doc = include_str!("docs2/deb_fallback_with.md"))]
555 #[must_use]
556 pub fn debug_fallback(mut self) -> Self {
557 self.value_str = format!("[default: {:?}]", self.value);
558 self
559 }
560}
561
562impl<P, T> ParseFallback<P, T> {
563 #[cfg_attr(not(doctest), doc = include_str!("docs2/format_fallback.md"))]
567 #[must_use]
568 pub fn format_fallback(
569 mut self,
570 format: impl Fn(&T, &mut std::fmt::Formatter<'_>) -> std::fmt::Result,
571 ) -> Self {
572 self.value_str = format!("[default: {}]", DisplayWith(&self.value, format));
573 self
574 }
575}
576
577impl<P, T: std::fmt::Display, F, E> ParseFallbackWith<T, P, F, E>
578where
579 F: Fn() -> Result<T, E>,
580{
581 #[cfg_attr(not(doctest), doc = include_str!("docs2/dis_fallback_with.md"))]
587 #[must_use]
588 pub fn display_fallback(mut self) -> Self {
589 if let Ok(val) = (self.fallback)() {
590 self.value_str = format!("[default: {}]", val);
591 }
592 self
593 }
594}
595
596impl<P, T: std::fmt::Debug, F, E> ParseFallbackWith<T, P, F, E>
597where
598 F: Fn() -> Result<T, E>,
599{
600 #[cfg_attr(not(doctest), doc = include_str!("docs2/deb_fallback.md"))]
606 #[must_use]
607 pub fn debug_fallback(mut self) -> Self {
608 if let Ok(val) = (self.fallback)() {
609 self.value_str = format!("[default: {:?}]", val);
610 }
611 self
612 }
613}
614
615impl<P, T, F, E> ParseFallbackWith<T, P, F, E>
616where
617 F: Fn() -> Result<T, E>,
618{
619 #[cfg_attr(not(doctest), doc = include_str!("docs2/format_fallback_with.md"))]
623 #[must_use]
624 pub fn format_fallback(
625 mut self,
626 format: impl Fn(&T, &mut std::fmt::Formatter<'_>) -> std::fmt::Result,
627 ) -> Self {
628 if let Ok(val) = (self.fallback)() {
629 self.value_str = format!("[default: {}]", DisplayWith(&val, format));
630 }
631 self
632 }
633}
634
635pub struct ParseGuard<P, F> {
637 pub(crate) inner: P,
638 pub(crate) check: F,
639 pub(crate) message: &'static str,
640}
641
642impl<T, P, F> Parser<T> for ParseGuard<P, F>
643where
644 P: Parser<T>,
645 F: Fn(&T) -> bool,
646{
647 fn eval(&self, args: &mut State) -> Result<T, Error> {
648 let t = self.inner.eval(args)?;
649 if (self.check)(&t) {
650 Ok(t)
651 } else {
652 Err(Error(Message::GuardFailed(args.current, self.message)))
653 }
654 }
655
656 fn meta(&self) -> Meta {
657 self.inner.meta()
658 }
659}
660
661pub struct ParseCount<P, T> {
664 pub(crate) inner: P,
665 pub(crate) ctx: PhantomData<T>,
666}
667
668impl<T, P> Parser<usize> for ParseCount<P, T>
669where
670 P: Parser<T>,
671{
672 fn eval(&self, args: &mut State) -> Result<usize, Error> {
673 let mut res = 0;
674 let mut current = args.len();
675 let mut len = usize::MAX;
676 while (parse_option(&self.inner, &mut len, args, false)?).is_some() {
677 res += 1;
678 if current == args.len() {
679 break;
680 }
681 current = args.len();
682 }
683 Ok(res)
684 }
685
686 fn meta(&self) -> Meta {
687 Meta::Many(Box::new(Meta::Optional(Box::new(self.inner.meta()))))
688 }
689}
690
691pub struct ParseLast<P> {
694 pub(crate) inner: P,
695}
696
697impl<T, P> Parser<T> for ParseLast<P>
698where
699 P: Parser<T>,
700{
701 fn eval(&self, args: &mut State) -> Result<T, Error> {
702 let mut last = None;
703 let mut current = args.len();
704 let mut len = usize::MAX;
705 while let Some(val) = parse_option(&self.inner, &mut len, args, false)? {
706 last = Some(val);
707 if current == args.len() {
708 break;
709 }
710 current = args.len();
711 }
712 if let Some(last) = last {
713 Ok(last)
714 } else {
715 self.inner.eval(args)
716 }
717 }
718
719 fn meta(&self) -> Meta {
720 Meta::Many(Box::new(Meta::Required(Box::new(self.inner.meta()))))
721 }
722}
723
724pub struct ParseOptional<P> {
728 pub(crate) inner: P,
729 pub(crate) catch: bool,
730}
731
732impl<T, P> Parser<Option<T>> for ParseOptional<P>
733where
734 P: Parser<T>,
735{
736 fn eval(&self, args: &mut State) -> Result<Option<T>, Error> {
737 let mut len = usize::MAX;
738 parse_option(&self.inner, &mut len, args, self.catch)
739 }
740
741 fn meta(&self) -> Meta {
742 Meta::Optional(Box::new(self.inner.meta()))
743 }
744}
745
746impl<P> ParseOptional<P> {
747 #[must_use]
748 #[cfg_attr(not(doctest), doc = include_str!("docs2/optional_catch.md"))]
765 pub fn catch(mut self) -> Self {
766 self.catch = true;
767 self
768 }
769}
770
771pub struct ParseMany<P> {
774 pub(crate) inner: P,
775 pub(crate) catch: bool,
776}
777
778impl<P> ParseMany<P> {
779 #[must_use]
780 #[cfg_attr(not(doctest), doc = include_str!("docs2/many_catch.md"))]
789 pub fn catch(mut self) -> Self {
790 self.catch = true;
791 self
792 }
793}
794
795fn parse_option<P, T>(
797 parser: &P,
798 len: &mut usize,
799 args: &mut State,
800 mut catch: bool,
801) -> Result<Option<T>, Error>
802where
803 P: Parser<T>,
804{
805 let mut orig_args = args.clone();
806 match parser.eval(args) {
807 Ok(val) => Ok(if args.len() < *len {
810 *len = args.len();
811 Some(val)
812 } else {
813 None
814 }),
815 Err(Error(err)) => {
816 let missing = matches!(err, Message::Missing(_));
828
829 catch &= !err.wrong_input();
830
831 if catch || (missing && orig_args.len() == args.len()) || (!missing && err.can_catch())
832 {
833 std::mem::swap(&mut orig_args, args);
834 #[cfg(feature = "autocomplete")]
835 if orig_args.comp_mut().is_some() {
836 args.swap_comps(&mut orig_args);
837 }
838 Ok(None)
839 } else {
840 Err(Error(err))
841 }
842 }
843 }
844}
845
846impl<T, P> Parser<Vec<T>> for ParseMany<P>
847where
848 P: Parser<T>,
849{
850 fn eval(&self, args: &mut State) -> Result<Vec<T>, Error> {
851 let mut len = usize::MAX;
852 std::iter::from_fn(|| parse_option(&self.inner, &mut len, args, self.catch).transpose())
853 .collect::<Result<Vec<T>, Error>>()
854 }
855
856 fn meta(&self) -> Meta {
857 Meta::Many(Box::new(Meta::Optional(Box::new(self.inner.meta()))))
858 }
859}
860
861pub struct ParsePure<T>(pub(crate) T);
864impl<T: Clone + 'static> Parser<T> for ParsePure<T> {
865 fn eval(&self, args: &mut State) -> Result<T, Error> {
866 args.current = None;
867 Ok(self.0.clone())
868 }
869
870 fn meta(&self) -> Meta {
871 Meta::Skip
872 }
873}
874
875pub struct ParsePureWith<T, F, E>(pub(crate) F)
876where
877 F: Fn() -> Result<T, E>,
878 E: ToString;
879impl<T: Clone + 'static, F: Fn() -> Result<T, E>, E: ToString> Parser<T>
880 for ParsePureWith<T, F, E>
881{
882 fn eval(&self, _args: &mut State) -> Result<T, Error> {
883 match (self.0)() {
884 Ok(ok) => Ok(ok),
885 Err(e) => Err(Error(Message::PureFailed(e.to_string()))),
886 }
887 }
888
889 fn meta(&self) -> Meta {
890 Meta::Skip
891 }
892}
893
894pub struct ParseFail<T> {
896 pub(crate) field1: &'static str,
897 pub(crate) field2: PhantomData<T>,
898}
899impl<T> Parser<T> for ParseFail<T> {
900 fn eval(&self, args: &mut State) -> Result<T, Error> {
901 args.current = None;
902 Err(Error(Message::ParseFail(self.field1)))
903 }
904
905 fn meta(&self) -> Meta {
906 Meta::Skip
907 }
908}
909
910pub struct ParseMap<T, P, F, R> {
912 pub(crate) inner: P,
913 pub(crate) inner_res: PhantomData<T>,
914 pub(crate) map_fn: F,
915 pub(crate) res: PhantomData<R>,
916}
917impl<P, T, F, R> Parser<R> for ParseMap<T, P, F, R>
918where
919 F: Fn(T) -> R,
920 P: Parser<T> + Sized,
921{
922 fn eval(&self, args: &mut State) -> Result<R, Error> {
923 let t = self.inner.eval(args)?;
924 Ok((self.map_fn)(t))
925 }
926
927 fn meta(&self) -> Meta {
928 self.inner.meta()
929 }
930}
931
932pub struct ParseCon<P> {
934 pub inner: P,
936 pub meta: Meta,
938 pub failfast: bool,
945}
946
947impl<T, P> Parser<T> for ParseCon<P>
948where
949 P: Fn(bool, &mut State) -> Result<T, Error>,
950{
951 fn eval(&self, args: &mut State) -> Result<T, Error> {
952 let res = (self.inner)(self.failfast, args);
953 args.current = None;
954 res
955 }
956
957 fn meta(&self) -> Meta {
958 self.meta.clone()
959 }
960}
961
962impl<T> ParseCon<T> {
963 #[must_use]
964 #[cfg_attr(not(doctest), doc = include_str!("docs2/adjacent_struct_0.md"))]
985 #[cfg_attr(not(doctest), doc = include_str!("docs2/adjacent_struct_1.md"))]
990 #[cfg_attr(not(doctest), doc = include_str!("docs2/adjacent_command.md"))]
996 #[cfg_attr(not(doctest), doc = include_str!("docs2/adjacent_struct_3.md"))]
1002 #[cfg_attr(not(doctest), doc = include_str!("docs2/adjacent_struct_4.md"))]
1011 pub fn adjacent(mut self) -> ParseAdjacent<Self> {
1023 self.failfast = true;
1024 ParseAdjacent { inner: self }
1025 }
1026}
1027
1028#[cfg(feature = "autocomplete")]
1030pub struct ParseComp<P, F> {
1031 pub(crate) inner: P,
1032 pub(crate) op: F,
1033 pub(crate) group: Option<String>,
1034}
1035
1036#[cfg(feature = "autocomplete")]
1037impl<P, F> ParseComp<P, F> {
1038 #[must_use]
1039 pub fn group(mut self, group: impl Into<String>) -> Self {
1041 self.group = Some(group.into());
1042 self
1043 }
1044}
1045
1046#[cfg(feature = "autocomplete")]
1047impl<P, T, F, M> Parser<T> for ParseComp<P, F>
1048where
1049 P: Parser<T> + Sized,
1050 M: Into<String>,
1051 F: Fn(&T) -> Vec<(M, Option<M>)>,
1052{
1053 fn eval(&self, args: &mut State) -> Result<T, Error> {
1054 let mut comp_items = Vec::new();
1056 args.swap_comps_with(&mut comp_items);
1057
1058 let res = self.inner.eval(args);
1059
1060 args.swap_comps_with(&mut comp_items);
1062
1063 if let Some(comp) = &mut args.comp_mut() {
1064 if res.is_err() {
1065 comp.extend_comps(comp_items);
1066 return res;
1067 }
1068 }
1069
1070 let res = res?;
1071
1072 let depth = args.depth();
1075 if let Some(comp) = &mut args.comp_mut() {
1076 for ci in comp_items {
1077 let is_meta = ci.is_metavar();
1078 if let Some(is_arg) = is_meta {
1079 let suggestions = (self.op)(&res);
1080 if suggestions.len() != 1 {
1082 comp.push_comp(ci);
1083 }
1084 for (replacement, description) in suggestions {
1085 let group = self.group.clone();
1086 comp.push_value(
1087 replacement.into(),
1088 description.map(Into::into),
1089 group,
1090 depth,
1091 is_arg,
1092 );
1093 }
1094 } else {
1095 comp.push_comp(ci);
1096 }
1097 }
1098 }
1099 Ok(res)
1100 }
1101
1102 fn meta(&self) -> Meta {
1103 self.inner.meta()
1104 }
1105}
1106
1107pub struct ParseAdjacent<P> {
1134 pub(crate) inner: P,
1135}
1136impl<P, T> Parser<T> for ParseAdjacent<P>
1137where
1138 P: Parser<T> + Sized,
1139{
1140 fn eval(&self, args: &mut State) -> Result<T, Error> {
1141 let original_scope = args.scope();
1142
1143 let first_item;
1144 let inner_meta = self.inner.meta();
1145 let mut best_error = if let Some(item) = Meta::first_item(&inner_meta) {
1146 first_item = item;
1147 let missing_item = MissingItem {
1148 item: item.clone(),
1149 position: original_scope.start,
1150 scope: original_scope.clone(),
1151 };
1152 Message::Missing(vec![missing_item])
1153 } else {
1154 unreachable!("bpaf usage BUG: adjacent should start with a required argument");
1155 };
1156 let mut best_args = args.clone();
1157 let mut best_consumed = 0;
1158
1159 for (start, width, mut this_arg) in args.ranges(first_item) {
1160 let mut scratch = this_arg.clone();
1169 scratch.set_scope(start..start + width);
1170 let before = scratch.len();
1171
1172 if before == 0 {
1176 continue;
1177 }
1178
1179 let _ = self.inner.eval(&mut scratch);
1180
1181 if before == scratch.len() {
1182 continue;
1184 }
1185
1186 this_arg.set_scope(start..original_scope.end);
1187 let before = this_arg.len();
1188
1189 if original_scope.end - start > before {
1192 this_arg.set_scope(this_arg.adjacently_available_from(start));
1193 }
1194
1195 loop {
1196 match self.inner.eval(&mut this_arg) {
1197 Ok(res) => {
1198 if let Some(adj_scope) = this_arg.adjacent_scope(args) {
1200 this_arg = args.clone();
1201 this_arg.set_scope(adj_scope);
1202 } else {
1203 std::mem::swap(args, &mut this_arg);
1204 args.set_scope(original_scope);
1205 return Ok(res);
1206 }
1207 }
1208 Err(Error(err)) => {
1209 let consumed = before - this_arg.len();
1210 if consumed > best_consumed {
1211 best_consumed = consumed;
1212 std::mem::swap(&mut best_args, &mut this_arg);
1213 best_error = err;
1214 }
1215 break;
1216 }
1217 }
1218 }
1219 }
1220
1221 std::mem::swap(args, &mut best_args);
1222 Err(Error(best_error))
1223 }
1224
1225 fn meta(&self) -> Meta {
1226 let meta = self.inner.meta();
1227 Meta::Adjacent(Box::new(meta))
1228 }
1229}
1230
1231impl<T> Parser<T> for Box<dyn Parser<T>> {
1232 fn eval(&self, args: &mut State) -> Result<T, Error> {
1233 self.as_ref().eval(args)
1234 }
1235 fn meta(&self) -> Meta {
1236 self.as_ref().meta()
1237 }
1238}