Skip to content

Commit

Permalink
docs(nom): Provide context for people used to nom
Browse files Browse the repository at this point in the history
Inspired by zslayton/cron#134
  • Loading branch information
epage committed Dec 30, 2024
1 parent 74c8472 commit 2606c4a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/_topic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! These are short recipes for accomplishing common tasks.
//!
//! - [Why `winnow`?][why]
//! - [Migrating from `nom`][nom]
//! - [For `nom` users][nom]
//! - Formats:
//! - [Elements of Programming Languages][language]
//! - [Arithmetic][arithmetic]
Expand Down
57 changes: 56 additions & 1 deletion src/_topic/nom.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! # Migrating from `nom`
//! # For `nom` users
//!
//! ## Migrating from `nom`
//!
//! For comparisons with `nom`, see
//! - [Why `winnow`][super::why]
Expand All @@ -10,6 +12,8 @@
//! of the `nom` combinator. It is expected that, where names diverge, a doc alias exists.
//! See also the [List of combinators][crate::combinator].
//!
//! ### Complex migrations
//!
//! For larger parsers, it is likely best to take smaller steps
//! - Easier to debug when something goes wrong
//! - Deprecation messages will help assist through the process
Expand All @@ -34,6 +38,8 @@
//! 1. Resolve deprecation messages
//! 1. Commit
//!
//! ### Examples
//!
//! For example migrations, see
//! - [git-config-env](https://github.com/gitext-rs/git-config-env/pull/11) (nom to winnow 0.3)
//! - [git-conventional](https://github.com/crate-ci/git-conventional/pull/37) (nom to winnow 0.3,
Expand All @@ -47,3 +53,52 @@
//! to winnow 0.5)
//! - [gitoxide](https://github.com/Byron/gitoxide/pull/956) (gradual migration from nom
//! to winnow 0.5)
//!
//! ## API differences
//!
//! ### Renamed APIs
//!
//! Names have changed for consistency or clarity.
//!
//! To find a parser you are looking for,
//! - Search the docs for the `nom` parser
//! - See the [List of combinators][crate::combinator]
//!
//! ### `&mut I`
//!
//! For an explanation of this change, see [Why `winnow`][super::why]
//!
//! To save and restore from intermediate states, [`Stream::checkpoint`] and [`Stream::reset`] can help:
//! ```rust
//! use winnow::stream::Stream as _;
//! # let mut i = "";
//! # let i = &mut i;
//!
//! let start = i.checkpoint();
//! // ...
//! i.reset(&start);
//! ```
//!
//! When the Output of a parser is a slice, you have to add a lifetime:
//! ```rust
//! # use winnow::prelude::*;
//! fn foo<'i>(i: &mut &'i str) -> PResult<&'i str> {
//! // ...
//! # winnow::combinator::rest.parse_next(i)
//! }
//! ```
//!
//! When writing a closure, you need to annotate the type:
//! ```rust
//! # use winnow::prelude::*;
//! # use winnow::combinator::trace;
//! fn foo(i: &mut &str) -> PResult<usize> {
//! trace("foo", |i: &mut _| {
//! // ...
//! # Ok(0)
//! }).parse_next(i)
//! }
//! ```
#![allow(unused_imports)]
use crate::stream::Stream;
22 changes: 21 additions & 1 deletion src/_topic/why.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
//! - Zero-copy parsing
//! - [Parse traces] for easier debugging
//! - [Streaming parsing][crate::Partial] for network communication or large file
//! - [Stateful][crate::Stateful] parsers
//! - [Stateful]] parsers
//!
//! For binary formats, `winnow` includes:
//! - [A hexadecimal view][crate::Bytes] in [trace]
Expand Down Expand Up @@ -74,6 +74,25 @@
//!
//! See also our [nom migration guide][super::nom]
//!
//! ### Design trade-offs
//!
//! `winnow` switched from pure-function parser (`Fn(I) -> (I, O)` to `Fn(&mut I) -> O`).
//! On error, `i` is left pointing at where the error happened.
//!
//! Benefits:
//! - Cleaner code: Removes need to pass `i` everywhere and makes changes to `i` more explicit
//! - Correctness: No forgetting to chain `i` through a parser
//! - Flexibility: `I` does not need to be `Copy` or even `Clone`. For example, [`Stateful`] can use `&mut S` instead of `RefCell<S>`.
//! - Performance: `Result::Ok` is smaller without `i`, reducing the risk that the output will be
//! returned on the stack, rather than the much faster CPU registers.
//! `Result::Err` can also be smaller because the error type does not need to carry `i` to point
//! to the error.
//! See also [#72](https://github.com/winnow-rs/winnow/issues/72).
//!
//! Downsides:
//! - When returning a slice, you have to add a lifetime (`fn foo<'i>(i: &mut &i str) -> PResult<&i str>`)
//! - When writing a closure, you need to annotate the type (`|i: &mut _|`, at least the full type isn't needed)
//!
//! ## `chumsky`
//!
//! [`chumsky`](https://crates.io/crates/chumsky) is an up and coming parser-combinator library
Expand Down Expand Up @@ -104,3 +123,4 @@
use crate::binary::length_take;
use crate::combinator::trace;
use crate::stream::Accumulate;
use crate::stream::Stateful;

0 comments on commit 2606c4a

Please sign in to comment.