• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::combinator::trace;
2 use crate::error::ParserError;
3 use crate::stream::Stream;
4 use crate::*;
5 
6 #[doc(inline)]
7 pub use crate::seq;
8 
9 /// Sequence two parsers, only returning the output from the second.
10 ///
11 /// See also [`seq`] to generalize this across any number of fields.
12 ///
13 /// # Example
14 ///
15 /// ```rust
16 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
17 /// # use winnow::prelude::*;
18 /// # use winnow::error::Needed::Size;
19 /// use winnow::combinator::preceded;
20 ///
21 /// let mut parser = preceded("abc", "efg");
22 ///
23 /// assert_eq!(parser.parse_peek("abcefg"), Ok(("", "efg")));
24 /// assert_eq!(parser.parse_peek("abcefghij"), Ok(("hij", "efg")));
25 /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
26 /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
27 /// ```
28 #[doc(alias = "ignore_then")]
preceded<Input, Ignored, Output, Error, IgnoredParser, ParseNext>( mut ignored: IgnoredParser, mut parser: ParseNext, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, IgnoredParser: Parser<Input, Ignored, Error>, ParseNext: Parser<Input, Output, Error>,29 pub fn preceded<Input, Ignored, Output, Error, IgnoredParser, ParseNext>(
30     mut ignored: IgnoredParser,
31     mut parser: ParseNext,
32 ) -> impl Parser<Input, Output, Error>
33 where
34     Input: Stream,
35     Error: ParserError<Input>,
36     IgnoredParser: Parser<Input, Ignored, Error>,
37     ParseNext: Parser<Input, Output, Error>,
38 {
39     trace("preceded", move |input: &mut Input| {
40         let _ = ignored.parse_next(input)?;
41         parser.parse_next(input)
42     })
43 }
44 
45 /// Sequence two parsers, only returning the output of the first.
46 ///
47 /// See also [`seq`] to generalize this across any number of fields.
48 ///
49 /// # Example
50 ///
51 /// ```rust
52 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
53 /// # use winnow::prelude::*;
54 /// # use winnow::error::Needed::Size;
55 /// use winnow::combinator::terminated;
56 ///
57 /// let mut parser = terminated("abc", "efg");
58 ///
59 /// assert_eq!(parser.parse_peek("abcefg"), Ok(("", "abc")));
60 /// assert_eq!(parser.parse_peek("abcefghij"), Ok(("hij", "abc")));
61 /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
62 /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
63 /// ```
64 #[doc(alias = "then_ignore")]
terminated<Input, Output, Ignored, Error, ParseNext, IgnoredParser>( mut parser: ParseNext, mut ignored: IgnoredParser, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, ParseNext: Parser<Input, Output, Error>, IgnoredParser: Parser<Input, Ignored, Error>,65 pub fn terminated<Input, Output, Ignored, Error, ParseNext, IgnoredParser>(
66     mut parser: ParseNext,
67     mut ignored: IgnoredParser,
68 ) -> impl Parser<Input, Output, Error>
69 where
70     Input: Stream,
71     Error: ParserError<Input>,
72     ParseNext: Parser<Input, Output, Error>,
73     IgnoredParser: Parser<Input, Ignored, Error>,
74 {
75     trace("terminated", move |input: &mut Input| {
76         let o = parser.parse_next(input)?;
77         ignored.parse_next(input).map(|_| o)
78     })
79 }
80 
81 /// Sequence three parsers, only returning the values of the first and third.
82 ///
83 /// See also [`seq`] to generalize this across any number of fields.
84 ///
85 /// # Example
86 ///
87 /// ```rust
88 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
89 /// # use winnow::error::Needed::Size;
90 /// # use winnow::prelude::*;
91 /// use winnow::combinator::separated_pair;
92 ///
93 /// let mut parser = separated_pair("abc", "|", "efg");
94 ///
95 /// assert_eq!(parser.parse_peek("abc|efg"), Ok(("", ("abc", "efg"))));
96 /// assert_eq!(parser.parse_peek("abc|efghij"), Ok(("hij", ("abc", "efg"))));
97 /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
98 /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
99 /// ```
separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>( mut first: P1, mut sep: SepParser, mut second: P2, ) -> impl Parser<Input, (O1, O2), Error> where Input: Stream, Error: ParserError<Input>, P1: Parser<Input, O1, Error>, SepParser: Parser<Input, Sep, Error>, P2: Parser<Input, O2, Error>,100 pub fn separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>(
101     mut first: P1,
102     mut sep: SepParser,
103     mut second: P2,
104 ) -> impl Parser<Input, (O1, O2), Error>
105 where
106     Input: Stream,
107     Error: ParserError<Input>,
108     P1: Parser<Input, O1, Error>,
109     SepParser: Parser<Input, Sep, Error>,
110     P2: Parser<Input, O2, Error>,
111 {
112     trace("separated_pair", move |input: &mut Input| {
113         let o1 = first.parse_next(input)?;
114         let _ = sep.parse_next(input)?;
115         second.parse_next(input).map(|o2| (o1, o2))
116     })
117 }
118 
119 /// Sequence three parsers, only returning the output of the second.
120 ///
121 /// See also [`seq`] to generalize this across any number of fields.
122 ///
123 /// # Example
124 ///
125 /// ```rust
126 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
127 /// # use winnow::error::Needed::Size;
128 /// # use winnow::prelude::*;
129 /// use winnow::combinator::delimited;
130 ///
131 /// let mut parser = delimited("(", "abc", ")");
132 ///
133 /// assert_eq!(parser.parse_peek("(abc)"), Ok(("", "abc")));
134 /// assert_eq!(parser.parse_peek("(abc)def"), Ok(("def", "abc")));
135 /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
136 /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
137 /// ```
138 #[doc(alias = "between")]
139 #[doc(alias = "padded")]
delimited< Input, Ignored1, Output, Ignored2, Error, IgnoredParser1, ParseNext, IgnoredParser2, >( mut ignored1: IgnoredParser1, mut parser: ParseNext, mut ignored2: IgnoredParser2, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, IgnoredParser1: Parser<Input, Ignored1, Error>, ParseNext: Parser<Input, Output, Error>, IgnoredParser2: Parser<Input, Ignored2, Error>,140 pub fn delimited<
141     Input,
142     Ignored1,
143     Output,
144     Ignored2,
145     Error,
146     IgnoredParser1,
147     ParseNext,
148     IgnoredParser2,
149 >(
150     mut ignored1: IgnoredParser1,
151     mut parser: ParseNext,
152     mut ignored2: IgnoredParser2,
153 ) -> impl Parser<Input, Output, Error>
154 where
155     Input: Stream,
156     Error: ParserError<Input>,
157     IgnoredParser1: Parser<Input, Ignored1, Error>,
158     ParseNext: Parser<Input, Output, Error>,
159     IgnoredParser2: Parser<Input, Ignored2, Error>,
160 {
161     trace("delimited", move |input: &mut Input| {
162         let _ = ignored1.parse_next(input)?;
163         let o2 = parser.parse_next(input)?;
164         ignored2.parse_next(input).map(|_| o2)
165     })
166 }
167