1use crate::prelude::*;
2
3pub mod identifiers;
4pub mod types;
5
6pub(crate) use traits::*;
7pub(crate) use traits::impl_from_str_nom;
8pub use traits::PublicCommandOutput;
9mod traits;
10
11pub(crate) fn ws<'a, F: 'a, O, E: nom::error::ParseError<&'a str>>(
14 inner: F,
15) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
16where
17 F: Fn(&'a str) -> IResult<&'a str, O, E>,
18{
19 delimited(multispace0, inner, multispace0)
20}
21
22#[cfg(any(test, doctest))]
31fn assert_nom_parses<T: NomFromStr + std::fmt::Display + std::fmt::Debug>(
32 examples: impl IntoIterator<Item = &'static str>,
33 successfully_parsed: impl Fn(&T) -> bool,
34) {
35 use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
36
37 let fmt_verbose_layer = tracing_subscriber::fmt::layer().pretty();
38
39 tracing_subscriber::registry()
40 .with(fmt_verbose_layer)
41 .try_init()
42 .ok();
43
44 for example in examples.into_iter() {
45 let example = example.to_string();
46 match T::nom_from_str(&example) {
47 Ok((remaining, parsed)) => {
48 assert!(
49 remaining.is_empty(),
50 "Leftover input {:?} while parsing {} into {:?}",
51 remaining,
52 example,
53 parsed
54 );
55 assert_eq!(
56 parsed.to_string(),
57 example,
58 "Parsing {} into {:?} didn't match Display of {}",
59 example,
60 parsed,
61 example
62 );
63 assert!(
64 successfully_parsed(&parsed),
65 "While parsing {}, got unimplemented variant {:?}",
66 example,
67 parsed
68 );
69 }
70 Err(err) => {
71 panic!("Failed to parse {:?}: {}", example, err);
72 }
73 }
74 }
75}