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" )] |
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(name:"preceded" , parser: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" )] |
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(name:"terminated" , parser:move |input: &mut Input| { |
76 | let o: Output = 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 | /// ``` |
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(name:"separated_pair" , parser:move |input: &mut Input| { |
113 | let o1: O1 = first.parse_next(input)?; |
114 | let _ = sep.parse_next(input)?; |
115 | second.parse_next(input).map(|o2: 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" )] |
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(name:"delimited" , parser:move |input: &mut Input| { |
162 | let _ = ignored1.parse_next(input)?; |
163 | let o2: Output = parser.parse_next(input)?; |
164 | ignored2.parse_next(input).map(|_| o2) |
165 | }) |
166 | } |
167 | |