nom_config_in/
util.rs

1use std::ops::{Range, RangeFrom, RangeTo};
2
3use nom::{
4    branch::alt,
5    bytes::complete::tag,
6    character::complete::{line_ending, multispace1, not_line_ending, space1},
7    combinator::{eof, value},
8    error::ParseError,
9    multi::many0,
10    sequence::{preceded, terminated},
11    AsChar, Compare, IResult, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice,
12};
13
14pub fn ws_comment<I, E: ParseError<I>>(input: I) -> IResult<I, (), E>
15where
16    I: Clone + InputLength + InputTake,
17    I: InputTakeAtPosition,
18    <I as InputTakeAtPosition>::Item: AsChar + Clone,
19    <I as InputIter>::Item: Clone,
20    I: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
21    I: InputIter + InputLength,
22    I: Compare<&'static str>,
23    <I as InputIter>::Item: AsChar,
24    <I as InputIter>::Item: AsChar,
25{
26    value(
27        (),
28        many0(alt((
29            preceded(
30                alt((tag("#"), tag("\\#"))),
31                terminated(not_line_ending, alt((line_ending, eof))),
32            ),
33            preceded(
34                tag(":"),
35                terminated(not_line_ending, alt((line_ending, eof))),
36            ),
37            preceded(tag(r#"\"#), line_ending),
38            preceded(
39                tag("*"),
40                terminated(not_line_ending, alt((line_ending, eof))),
41            ),
42            multispace1,
43            // TODO linux v3.2, in file /drivers/dma/Kconfig
44            tag(" "),
45        ))),
46    )(input)
47}
48
49pub fn ws<I, F, O, E: ParseError<I>>(inner: F) -> impl FnMut(I) -> IResult<I, O, E>
50where
51    I: Clone + InputLength + InputTake,
52    <I as InputIter>::Item: Clone,
53    I: InputTakeAtPosition,
54    <I as InputTakeAtPosition>::Item: AsChar + Clone,
55    I: InputTakeAtPosition,
56    <I as InputTakeAtPosition>::Item: AsChar,
57    I: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
58    I: InputIter + InputLength,
59    I: Compare<&'static str>,
60    <I as InputIter>::Item: AsChar,
61    <I as InputIter>::Item: AsChar,
62    F: FnMut(I) -> IResult<I, O, E>,
63{
64    preceded(ws_comment, inner)
65}
66
67/// Gets rid of spaces, tabs and backslash + newline.
68/// `wsi` for *whitespaces inline*
69/// # Example
70/// ```
71/// use nom::bytes::complete::tag;
72/// use nom_config_in::util::wsi;
73/// let input = r#"   \
74/// hello"#;
75/// assert_eq!(wsi(tag::<&str, &str, ()>("hello"))(input), Ok(("", "hello")))
76/// ```
77pub fn wsi<I, F, O, E: ParseError<I>>(inner: F) -> impl FnMut(I) -> IResult<I, O, E>
78where
79    I: Clone + InputLength + InputTake,
80    <I as InputIter>::Item: Clone,
81    I: InputTakeAtPosition,
82    <I as InputTakeAtPosition>::Item: AsChar + Clone,
83    I: InputTakeAtPosition,
84    <I as InputTakeAtPosition>::Item: AsChar,
85    I: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
86    I: InputIter + InputLength,
87    I: Compare<&'static str>,
88    <I as InputIter>::Item: AsChar,
89    <I as InputIter>::Item: AsChar,
90    F: FnMut(I) -> IResult<I, O, E>,
91{
92    preceded(
93        value((), many0(alt((preceded(tag("\\"), line_ending), space1)))),
94        inner,
95    )
96}