Skip to content

Commit

Permalink
docs(examples): Move away from ModalResult where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Jan 24, 2025
1 parent 9c63459 commit 909d4bc
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 34 deletions.
9 changes: 5 additions & 4 deletions examples/arithmetic/parser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::str::FromStr;

use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
Expand All @@ -11,7 +12,7 @@ use winnow::{

// Parser definition

pub(crate) fn expr(i: &mut &str) -> ModalResult<i64> {
pub(crate) fn expr(i: &mut &str) -> Result<i64> {
let init = term.parse_next(i)?;

repeat(0.., (one_of(['+', '-']), term))
Expand All @@ -31,7 +32,7 @@ pub(crate) fn expr(i: &mut &str) -> ModalResult<i64> {
// We read an initial factor and for each time we find
// a * or / operator followed by another factor, we do
// the math by folding everything
fn term(i: &mut &str) -> ModalResult<i64> {
fn term(i: &mut &str) -> Result<i64> {
let init = factor.parse_next(i)?;

repeat(0.., (one_of(['*', '/']), factor))
Expand All @@ -52,7 +53,7 @@ fn term(i: &mut &str) -> ModalResult<i64> {
// We look for a digit suite, and try to convert it.
// If either str::from_utf8 or FromStr::from_str fail,
// we fallback to the parens parser defined above
fn factor(i: &mut &str) -> ModalResult<i64> {
fn factor(i: &mut &str) -> Result<i64> {
delimited(
multispaces,
alt((digits.try_map(FromStr::from_str), parens)),
Expand All @@ -62,7 +63,7 @@ fn factor(i: &mut &str) -> ModalResult<i64> {
}

// We parse any expr surrounded by parens, ignoring all whitespace around those
fn parens(i: &mut &str) -> ModalResult<i64> {
fn parens(i: &mut &str) -> Result<i64> {
delimited('(', expr, ')').parse_next(i)
}

Expand Down
9 changes: 5 additions & 4 deletions examples/arithmetic/parser_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;

use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
Expand Down Expand Up @@ -49,7 +50,7 @@ impl Display for Expr {
}
}

pub(crate) fn expr(i: &mut &str) -> ModalResult<Expr> {
pub(crate) fn expr(i: &mut &str) -> Result<Expr> {
let init = term.parse_next(i)?;

repeat(0.., (one_of(['+', '-']), term))
Expand All @@ -66,7 +67,7 @@ pub(crate) fn expr(i: &mut &str) -> ModalResult<Expr> {
.parse_next(i)
}

fn term(i: &mut &str) -> ModalResult<Expr> {
fn term(i: &mut &str) -> Result<Expr> {
let init = factor.parse_next(i)?;

repeat(0.., (one_of(['*', '/']), factor))
Expand All @@ -83,7 +84,7 @@ fn term(i: &mut &str) -> ModalResult<Expr> {
.parse_next(i)
}

fn factor(i: &mut &str) -> ModalResult<Expr> {
fn factor(i: &mut &str) -> Result<Expr> {
delimited(
multispaces,
alt((digits.try_map(FromStr::from_str).map(Expr::Value), parens)),
Expand All @@ -92,7 +93,7 @@ fn factor(i: &mut &str) -> ModalResult<Expr> {
.parse_next(i)
}

fn parens(i: &mut &str) -> ModalResult<Expr> {
fn parens(i: &mut &str) -> Result<Expr> {
delimited("(", expr, ")")
.map(|e| Expr::Paren(Box::new(e)))
.parse_next(i)
Expand Down
15 changes: 8 additions & 7 deletions examples/arithmetic/parser_lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;

use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
Expand Down Expand Up @@ -98,16 +99,16 @@ impl<const LEN: usize> winnow::stream::ContainsToken<Token> for [Token; LEN] {
}

#[allow(dead_code)]
pub(crate) fn expr2(i: &mut &str) -> ModalResult<Expr> {
pub(crate) fn expr2(i: &mut &str) -> Result<Expr> {
let tokens = lex.parse_next(i)?;
expr.parse_next(&mut tokens.as_slice())
}

pub(crate) fn lex(i: &mut &str) -> ModalResult<Vec<Token>> {
pub(crate) fn lex(i: &mut &str) -> Result<Vec<Token>> {
preceded(multispaces, repeat(1.., terminated(token, multispaces))).parse_next(i)
}

fn token(i: &mut &str) -> ModalResult<Token> {
fn token(i: &mut &str) -> Result<Token> {
dispatch! {peek(any);
'0'..='9' => digits.try_map(FromStr::from_str).map(Token::Value),
'(' => '('.value(Token::OpenParen),
Expand All @@ -121,7 +122,7 @@ fn token(i: &mut &str) -> ModalResult<Token> {
.parse_next(i)
}

pub(crate) fn expr(i: &mut &[Token]) -> ModalResult<Expr> {
pub(crate) fn expr(i: &mut &[Token]) -> Result<Expr> {
let init = term.parse_next(i)?;

repeat(
Expand All @@ -144,7 +145,7 @@ pub(crate) fn expr(i: &mut &[Token]) -> ModalResult<Expr> {
.parse_next(i)
}

fn term(i: &mut &[Token]) -> ModalResult<Expr> {
fn term(i: &mut &[Token]) -> Result<Expr> {
let init = factor.parse_next(i)?;

repeat(
Expand All @@ -167,7 +168,7 @@ fn term(i: &mut &[Token]) -> ModalResult<Expr> {
.parse_next(i)
}

fn factor(i: &mut &[Token]) -> ModalResult<Expr> {
fn factor(i: &mut &[Token]) -> Result<Expr> {
alt((
one_of(|t| matches!(t, Token::Value(_))).map(|t| match t {
Token::Value(v) => Expr::Value(v),
Expand All @@ -178,7 +179,7 @@ fn factor(i: &mut &[Token]) -> ModalResult<Expr> {
.parse_next(i)
}

fn parens(i: &mut &[Token]) -> ModalResult<Expr> {
fn parens(i: &mut &[Token]) -> Result<Expr> {
delimited(one_of(Token::OpenParen), expr, one_of(Token::CloseParen))
.map(|e| Expr::Paren(Box::new(e)))
.parse_next(i)
Expand Down
5 changes: 3 additions & 2 deletions examples/css/parser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use winnow::combinator::seq;
use winnow::prelude::*;
use winnow::token::take_while;
use winnow::Result;

#[derive(Debug, Eq, PartialEq)]
pub(crate) struct Color {
Expand All @@ -18,7 +19,7 @@ impl std::str::FromStr for Color {
}
}

pub(crate) fn hex_color(input: &mut &str) -> ModalResult<Color> {
pub(crate) fn hex_color(input: &mut &str) -> Result<Color> {
seq!(Color {
_: '#',
red: hex_primary,
Expand All @@ -28,7 +29,7 @@ pub(crate) fn hex_color(input: &mut &str) -> ModalResult<Color> {
.parse_next(input)
}

fn hex_primary(input: &mut &str) -> ModalResult<u8> {
fn hex_primary(input: &mut &str) -> Result<u8> {
take_while(2, |c: char| c.is_ascii_hexdigit())
.try_map(|input| u8::from_str_radix(input, 16))
.parse_next(input)
Expand Down
3 changes: 2 additions & 1 deletion examples/ini/bench.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use winnow::combinator::repeat;
use winnow::prelude::*;
use winnow::Result;

mod parser;
mod parser_str;
Expand Down Expand Up @@ -31,7 +32,7 @@ port=143
file=payroll.dat
\0";

fn acc<'s>(i: &mut parser::Stream<'s>) -> ModalResult<Vec<(&'s str, &'s str)>> {
fn acc<'s>(i: &mut parser::Stream<'s>) -> Result<Vec<(&'s str, &'s str)>> {
repeat(0.., parser::key_value).parse_next(i)
}

Expand Down
7 changes: 4 additions & 3 deletions examples/ini/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::str;

use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{alphanumeric1 as alphanumeric, multispace0 as multispace, space0 as space},
combinator::opt,
Expand All @@ -14,7 +15,7 @@ pub(crate) type Stream<'i> = &'i [u8];

pub(crate) fn categories<'s>(
i: &mut Stream<'s>,
) -> ModalResult<HashMap<&'s str, HashMap<&'s str, &'s str>>> {
) -> Result<HashMap<&'s str, HashMap<&'s str, &'s str>>> {
repeat(
0..,
separated_pair(
Expand All @@ -26,13 +27,13 @@ pub(crate) fn categories<'s>(
.parse_next(i)
}

fn category<'s>(i: &mut Stream<'s>) -> ModalResult<&'s str> {
fn category<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
delimited('[', take_while(0.., |c| c != b']'), ']')
.try_map(str::from_utf8)
.parse_next(i)
}

pub(crate) fn key_value<'s>(i: &mut Stream<'s>) -> ModalResult<(&'s str, &'s str)> {
pub(crate) fn key_value<'s>(i: &mut Stream<'s>) -> Result<(&'s str, &'s str)> {
let key = alphanumeric.try_map(str::from_utf8).parse_next(i)?;
let _ = (opt(space), '=', opt(space)).parse_next(i)?;
let val = take_while(0.., |c| c != b'\n' && c != b';')
Expand Down
15 changes: 8 additions & 7 deletions examples/ini/parser_str.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::HashMap;

use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{alphanumeric1 as alphanumeric, space0 as space},
combinator::opt,
Expand All @@ -13,27 +14,27 @@ pub(crate) type Stream<'i> = &'i str;

pub(crate) fn categories<'s>(
input: &mut Stream<'s>,
) -> ModalResult<HashMap<&'s str, HashMap<&'s str, &'s str>>> {
) -> Result<HashMap<&'s str, HashMap<&'s str, &'s str>>> {
repeat(0.., category_and_keys).parse_next(input)
}

fn category_and_keys<'s>(i: &mut Stream<'s>) -> ModalResult<(&'s str, HashMap<&'s str, &'s str>)> {
fn category_and_keys<'s>(i: &mut Stream<'s>) -> Result<(&'s str, HashMap<&'s str, &'s str>)> {
(category, keys_and_values).parse_next(i)
}

fn category<'s>(i: &mut Stream<'s>) -> ModalResult<&'s str> {
fn category<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
terminated(
delimited('[', take_while(0.., |c| c != ']'), ']'),
opt(take_while(1.., [' ', '\r', '\n'])),
)
.parse_next(i)
}

fn keys_and_values<'s>(input: &mut Stream<'s>) -> ModalResult<HashMap<&'s str, &'s str>> {
fn keys_and_values<'s>(input: &mut Stream<'s>) -> Result<HashMap<&'s str, &'s str>> {
repeat(0.., key_value).parse_next(input)
}

fn key_value<'s>(i: &mut Stream<'s>) -> ModalResult<(&'s str, &'s str)> {
fn key_value<'s>(i: &mut Stream<'s>) -> Result<(&'s str, &'s str)> {
let key = alphanumeric.parse_next(i)?;
let _ = (opt(space), "=", opt(space)).parse_next(i)?;
let val = take_till(0.., is_line_ending_or_comment).parse_next(i)?;
Expand All @@ -48,11 +49,11 @@ fn is_line_ending_or_comment(chr: char) -> bool {
chr == ';' || chr == '\n'
}

fn till_line_ending<'s>(i: &mut Stream<'s>) -> ModalResult<&'s str> {
fn till_line_ending<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
take_while(0.., |c| c != '\r' && c != '\n').parse_next(i)
}

fn space_or_line_ending<'s>(i: &mut Stream<'s>) -> ModalResult<&'s str> {
fn space_or_line_ending<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
take_while(1.., [' ', '\r', '\n']).parse_next(i)
}

Expand Down
13 changes: 7 additions & 6 deletions examples/string/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ use winnow::combinator::{delimited, preceded};
use winnow::error::{FromExternalError, ParserError};
use winnow::prelude::*;
use winnow::token::{take_till, take_while};
use winnow::Result;

/// Parse a string. Use a loop of `parse_fragment` and push all of the fragments
/// into an output string.
pub(crate) fn parse_string<'a, E>(input: &mut &'a str) -> ModalResult<String, E>
pub(crate) fn parse_string<'a, E>(input: &mut &'a str) -> Result<String, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
Expand Down Expand Up @@ -64,7 +65,7 @@ enum StringFragment<'a> {

/// Combine `parse_literal`, `parse_escaped_whitespace`, and `parse_escaped_char`
/// into a `StringFragment`.
fn parse_fragment<'a, E>(input: &mut &'a str) -> ModalResult<StringFragment<'a>, E>
fn parse_fragment<'a, E>(input: &mut &'a str) -> Result<StringFragment<'a>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
Expand All @@ -79,7 +80,7 @@ where
}

/// Parse a non-empty block of text that doesn't include \ or "
fn parse_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> ModalResult<&'a str, E> {
fn parse_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> Result<&'a str, E> {
// `take_till` parses a string of 0 or more characters that aren't one of the
// given characters.
let not_quote_slash = take_till(1.., ['"', '\\']);
Expand All @@ -98,7 +99,7 @@ fn parse_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> ModalResul
// then combine them into larger parsers.

/// Parse an escaped character: \n, \t, \r, \u{00AC}, etc.
fn parse_escaped_char<'a, E>(input: &mut &'a str) -> ModalResult<char, E>
fn parse_escaped_char<'a, E>(input: &mut &'a str) -> Result<char, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
Expand Down Expand Up @@ -128,7 +129,7 @@ where
/// Parse a unicode sequence, of the form u{XXXX}, where XXXX is 1 to 6
/// hexadecimal numerals. We will combine this later with `parse_escaped_char`
/// to parse sequences like \u{00AC}.
fn parse_unicode<'a, E>(input: &mut &'a str) -> ModalResult<char, E>
fn parse_unicode<'a, E>(input: &mut &'a str) -> Result<char, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
Expand Down Expand Up @@ -162,6 +163,6 @@ where
/// to discard any escaped whitespace.
fn parse_escaped_whitespace<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> ModalResult<&'a str, E> {
) -> Result<&'a str, E> {
preceded('\\', multispace1).parse_next(input)
}

0 comments on commit 909d4bc

Please sign in to comment.