Skip to content

Commit

Permalink
Merge pull request #238 from epage/macro
Browse files Browse the repository at this point in the history
WIP: feat(seq): 'seq' macro for easier skipping
  • Loading branch information
epage authored Dec 18, 2023
2 parents 2684e00 + 3440c97 commit 30ac3f8
Show file tree
Hide file tree
Showing 8 changed files with 658 additions and 37 deletions.
12 changes: 8 additions & 4 deletions examples/css/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use winnow::combinator::seq;
use winnow::prelude::*;
use winnow::token::take_while;

Expand All @@ -18,10 +19,13 @@ impl std::str::FromStr for Color {
}

pub fn hex_color(input: &mut &str) -> PResult<Color> {
let _ = "#".parse_next(input)?;
let (red, green, blue) = (hex_primary, hex_primary, hex_primary).parse_next(input)?;

Ok(Color { red, green, blue })
seq!(Color {
_: '#',
red: hex_primary,
green: hex_primary,
blue: hex_primary
})
.parse_next(input)
}

fn hex_primary(input: &mut &str) -> PResult<u8> {
Expand Down
31 changes: 15 additions & 16 deletions examples/http/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use winnow::combinator::seq;
use winnow::prelude::*;
use winnow::{ascii::line_ending, combinator::repeat, token::take_while};

Expand Down Expand Up @@ -51,18 +52,15 @@ fn request<'s>(input: &mut Stream<'s>) -> PResult<(Request<'s>, Vec<Header<'s>>)
}

fn request_line<'s>(input: &mut Stream<'s>) -> PResult<Request<'s>> {
let method = take_while(1.., is_token).parse_next(input)?;
let _ = take_while(1.., is_space).parse_next(input)?;
let uri = take_while(1.., is_not_space).parse_next(input)?;
let _ = take_while(1.., is_space).parse_next(input)?;
let version = http_version(input)?;
let _ = line_ending.parse_next(input)?;

Ok(Request {
method,
uri,
version,
seq!( Request {
method: take_while(1.., is_token),
_: take_while(1.., is_space),
uri: take_while(1.., is_not_space),
_: take_while(1.., is_space),
version: http_version,
_: line_ending,
})
.parse_next(input)
}

fn http_version<'s>(input: &mut Stream<'s>) -> PResult<&'s [u8]> {
Expand All @@ -81,11 +79,12 @@ fn message_header_value<'s>(input: &mut Stream<'s>) -> PResult<&'s [u8]> {
}

fn message_header<'s>(input: &mut Stream<'s>) -> PResult<Header<'s>> {
let name = take_while(1.., is_token).parse_next(input)?;
let _ = ':'.parse_next(input)?;
let value = repeat(1.., message_header_value).parse_next(input)?;

Ok(Header { name, value })
seq!(Header {
name: take_while(1.., is_token),
_: ':',
value: repeat(1.., message_header_value),
})
.parse_next(input)
}

#[rustfmt::skip]
Expand Down
31 changes: 15 additions & 16 deletions examples/http/parser_streaming.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use winnow::combinator::seq;
use winnow::{
ascii::line_ending, combinator::repeat, prelude::*, stream::Partial, token::take_while,
};
Expand Down Expand Up @@ -52,18 +53,15 @@ fn request<'s>(input: &mut Stream<'s>) -> PResult<(Request<'s>, Vec<Header<'s>>)
}

fn request_line<'s>(input: &mut Stream<'s>) -> PResult<Request<'s>> {
let method = take_while(1.., is_token).parse_next(input)?;
let _ = take_while(1.., is_space).parse_next(input)?;
let uri = take_while(1.., is_not_space).parse_next(input)?;
let _ = take_while(1.., is_space).parse_next(input)?;
let version = http_version(input)?;
let _ = line_ending.parse_next(input)?;

Ok(Request {
method,
uri,
version,
seq!( Request {
method: take_while(1.., is_token),
_: take_while(1.., is_space),
uri: take_while(1.., is_not_space),
_: take_while(1.., is_space),
version: http_version,
_: line_ending,
})
.parse_next(input)
}

fn http_version<'s>(input: &mut Stream<'s>) -> PResult<&'s [u8]> {
Expand All @@ -82,11 +80,12 @@ fn message_header_value<'s>(input: &mut Stream<'s>) -> PResult<&'s [u8]> {
}

fn message_header<'s>(input: &mut Stream<'s>) -> PResult<Header<'s>> {
let name = take_while(1.., is_token).parse_next(input)?;
let _ = ':'.parse_next(input)?;
let value = repeat(1.., message_header_value).parse_next(input)?;

Ok(Header { name, value })
seq!(Header {
name: take_while(1.., is_token),
_: ':',
value: repeat(1.., message_header_value),
})
.parse_next(input)
}

#[rustfmt::skip]
Expand Down
1 change: 1 addition & 0 deletions src/combinator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
//! | combinator | usage | input | new input | output | comment |
//! |---|---|---|---|---|---|
//! | [`(...)` (tuples)][crate::Parser] | `("ab", "XY", take(1))` | `"abXYZ!"` | `"!"` | `Ok(("ab", "XY", "Z"))` |Chains parsers and assemble the sub results in a tuple. You can use as many child parsers as you can put elements in a tuple|
//! | [`seq!`] | `seq!(_: char('('), take(2), _: char(')'))` | `"(ab)cd"` | `"cd"` | `Ok("ab")` ||
//! | [`delimited`] | `delimited(char('('), take(2), char(')'))` | `"(ab)cd"` | `"cd"` | `Ok("ab")` ||
//! | [`preceded`] | `preceded("ab", "XY")` | `"abXYZ"` | `"Z"` | `Ok("XY")` ||
//! | [`terminated`] | `terminated("ab", "XY")` | `"abXYZ"` | `"Z"` | `Ok("ab")` ||
Expand Down
11 changes: 11 additions & 0 deletions src/combinator/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ use crate::stream::Stream;
use crate::trace::trace;
use crate::*;

#[doc(inline)]
pub use crate::seq;

/// Sequence two parsers, only returning the output from the second.
///
/// # Arguments
/// * `first` The opening parser.
/// * `second` The second parser to get object.
///
/// See also [`seq`] to generalize this across any number of fields.
///
/// # Example
///
/// ```rust
Expand Down Expand Up @@ -47,6 +52,8 @@ where
/// * `first` The first parser to apply.
/// * `second` The second parser to match an object.
///
/// See also [`seq`] to generalize this across any number of fields.
///
/// # Example
///
/// ```rust
Expand Down Expand Up @@ -86,6 +93,8 @@ where
/// * `sep` The separator parser to apply.
/// * `second` The second parser to apply.
///
/// See also [`seq`] to generalize this across any number of fields.
///
/// # Example
///
/// ```rust
Expand Down Expand Up @@ -127,6 +136,8 @@ where
/// * `second` The second parser to apply.
/// * `third` The third parser to apply and discard.
///
/// See also [`seq`] to generalize this across any number of fields.
///
/// # Example
///
/// ```rust
Expand Down
1 change: 1 addition & 0 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod dispatch;
mod seq;

#[cfg(test)]
mod test;
Loading

0 comments on commit 30ac3f8

Please sign in to comment.