aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid LeGare <legare@google.com>2022-03-04 23:31:13 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-03-04 23:31:13 +0000
commit33e245682495f988c4e003215a1fda28aa26cf6d (patch)
tree63d0f458744432dcb2f047ae214ace796e4a431d
parentd05de513297c6186f05743855e05629aef6111b3 (diff)
parent213f0f9b944d8bc8c0172ab6899567dd413570c1 (diff)
downloadnom-android13-qpr2-s9-release.tar.gz
Update nom to 7.1.0 am: 061b49860e am: 3c3372eb2a am: 213f0f9b94t_frc_odp_330442040t_frc_odp_330442000t_frc_ase_330444010android-13.0.0_r83android-13.0.0_r82android-13.0.0_r81android-13.0.0_r80android-13.0.0_r79android-13.0.0_r78android-13.0.0_r77android-13.0.0_r76android-13.0.0_r75android-13.0.0_r74android-13.0.0_r73android-13.0.0_r72android-13.0.0_r71android-13.0.0_r70android-13.0.0_r69android-13.0.0_r68android-13.0.0_r67android-13.0.0_r66android-13.0.0_r65android-13.0.0_r64android-13.0.0_r63android-13.0.0_r62android-13.0.0_r61android-13.0.0_r60android-13.0.0_r59android-13.0.0_r58android-13.0.0_r57android-13.0.0_r56android-13.0.0_r55android-13.0.0_r54android-13.0.0_r53android-13.0.0_r52android-13.0.0_r51android-13.0.0_r50android-13.0.0_r49android-13.0.0_r48android-13.0.0_r47android-13.0.0_r46android-13.0.0_r45android-13.0.0_r44android-13.0.0_r43android-13.0.0_r42android-13.0.0_r41android-13.0.0_r40android-13.0.0_r39android-13.0.0_r38android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android-13.0.0_r30android-13.0.0_r29android-13.0.0_r28android-13.0.0_r27android-13.0.0_r24android-13.0.0_r23android-13.0.0_r22android-13.0.0_r21android-13.0.0_r20android-13.0.0_r19android-13.0.0_r18android-13.0.0_r17android-13.0.0_r16aml_go_odp_330912000aml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-qpr3-s9-releaseandroid13-qpr3-s8-releaseandroid13-qpr3-s7-releaseandroid13-qpr3-s6-releaseandroid13-qpr3-s5-releaseandroid13-qpr3-s4-releaseandroid13-qpr3-s3-releaseandroid13-qpr3-s2-releaseandroid13-qpr3-s14-releaseandroid13-qpr3-s13-releaseandroid13-qpr3-s12-releaseandroid13-qpr3-s11-releaseandroid13-qpr3-s10-releaseandroid13-qpr3-s1-releaseandroid13-qpr3-releaseandroid13-qpr3-c-s8-releaseandroid13-qpr3-c-s7-releaseandroid13-qpr3-c-s6-releaseandroid13-qpr3-c-s5-releaseandroid13-qpr3-c-s4-releaseandroid13-qpr3-c-s3-releaseandroid13-qpr3-c-s2-releaseandroid13-qpr3-c-s12-releaseandroid13-qpr3-c-s11-releaseandroid13-qpr3-c-s10-releaseandroid13-qpr3-c-s1-releaseandroid13-qpr2-s9-releaseandroid13-qpr2-s8-releaseandroid13-qpr2-s7-releaseandroid13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s12-releaseandroid13-qpr2-s11-releaseandroid13-qpr2-s10-releaseandroid13-qpr2-s1-releaseandroid13-qpr2-releaseandroid13-qpr2-b-s1-releaseandroid13-qpr1-s8-releaseandroid13-qpr1-s7-releaseandroid13-qpr1-s6-releaseandroid13-qpr1-s5-releaseandroid13-qpr1-s4-releaseandroid13-qpr1-s3-releaseandroid13-qpr1-s2-releaseandroid13-qpr1-s1-releaseandroid13-qpr1-releaseandroid13-mainline-go-adservices-releaseandroid13-frc-odp-releaseandroid13-devandroid13-d4-s2-releaseandroid13-d4-s1-releaseandroid13-d4-releaseandroid13-d3-s1-releaseandroid13-d2-release
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/nom/+/2005952 Change-Id: Idf470832e8456a97dcd47fc7b0313fc859d874ef
-rw-r--r--.cargo_vcs_info.json4
-rw-r--r--Android.bp2
-rw-r--r--CHANGELOG.md42
-rw-r--r--Cargo.toml55
-rw-r--r--Cargo.toml.orig57
-rw-r--r--METADATA10
-rw-r--r--README.md8
-rw-r--r--src/bits/complete.rs2
-rw-r--r--src/bits/streaming.rs51
-rw-r--r--src/branch/mod.rs12
-rw-r--r--src/bytes/complete.rs14
-rw-r--r--src/bytes/streaming.rs16
-rw-r--r--src/combinator/mod.rs23
-rw-r--r--src/internal.rs2
-rw-r--r--src/lib.rs18
-rw-r--r--src/multi/mod.rs12
-rw-r--r--src/number/complete.rs85
-rw-r--r--src/number/streaming.rs84
-rw-r--r--src/sequence/mod.rs5
-rw-r--r--src/str.rs8
-rw-r--r--src/traits.rs2
-rw-r--r--tests/blockbuf-arithmetic.rs321
-rw-r--r--tests/issues.rs2
23 files changed, 301 insertions, 534 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index a624533..d603d8a 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "9678b061d3ed0a6b8e31ce569e024ec25f3dd354"
+ "sha1": "b6f79c4d375ae55e1fd1a35032ebb47a52ea3389"
}
-}
+} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 216642a..6fd9d6f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,7 @@ rust_library {
host_supported: true,
crate_name: "nom",
cargo_env_compat: true,
- cargo_pkg_version: "7.0.0",
+ cargo_pkg_version: "7.1.0",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 49ef3f5..a1bff5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,38 @@
### Changed
+## 7.1.0 - 2021-11-04
+
+### Thanks
+
+- @nickelc
+- @Stargateur
+- @NilsIrl
+- @clonejo
+- @Strytyp
+- @schubart
+- @jihchi
+- @nipunn1313
+- @Gungy2
+- @Drumato
+- @Alexhuszagh
+- @Aehmlo
+- @homersimpsons
+- @dne
+- @epage
+- @saiintbrisson
+- @pymongo
+
+### Changed
+
+- documentation fixes
+- Ci fixes
+- the move to minimal-lexical for float parsing introduced bugs that cannot be resolved right now, so this version moves back to using the standard lib' parser. *This is a performance regression**. If you have specific requirements around float parsing, you are strongly encouraged to use [recognize_float](https://docs.rs/nom/latest/nom/number/complete/fn.recognize_float.html) and another library to convert to a f32 or f64
+
+### Added
+
+- alt now works with 1 elment tuples
+
## 7.0.0 - 2021-08-21
This release fixes dependency compilation issues and strengthen the minimum supported Rust version (MSRV) policy. This is also the first release without the macros that were used since nom's beginning.
@@ -84,7 +116,7 @@ This release was done thanks to the hard work of (by order of appearance in the
- lots of documentation fixes
- relax trait bounds
-- workarounds for depenency issues with bitvec and memchr
+- workarounds for dependency issues with bitvec and memchr
## 6.1.2 - 2021-02-15
@@ -245,7 +277,7 @@ containing example patterns.
- removed the deprecated `whitespace` module
- the default error type is now a struct (`nom::error::Error`) instead of a tuple
- the `FromExternalError` allows wrapping the error returned by the function in the `map_res` combinator
-- renamed the `dbg!` macro to avoid conficts with `std::dbg!`
+- renamed the `dbg!` macro to avoid conflicts with `std::dbg!`
- `separated_list` now allows empty elements
@@ -256,7 +288,7 @@ containing example patterns.
- `success`: returns a value without consuming the input
- `satisfy`: checks a predicate over the next character
- `eof` function combinator
-- `consumed`: returnes the produced value and the consumed input
+- `consumed`: returns the produced value and the consumed input
- `length_count` function combinator
- `into`: converts a parser's output and error values if `From` implementations are available
- `IResult::finish()`: converts a parser's result to `Result<(I, O), E>` by removing the distinction between `Error` and `Failure` and panicking on `Incomplete`
@@ -1124,7 +1156,7 @@ Considering the number of changes since the last release, this version can conta
## 0.3.11 - 2015-08-04
### Thanks
-- @bluss for remarking that the crate included random junk lying non commited in my local repository
+- @bluss for remarking that the crate included random junk lying non committed in my local repository
### Fixed
- cleanup of my local repository will ship less files in the crates, resulting in a smaller download
@@ -1187,7 +1219,7 @@ Considering the number of changes since the last release, this version can conta
### Added
- documentation for a few functions
- the consumer trait now requires the `failed(&self, error_code)` method in case of parsing error
-- `named!` now handles thge alternative `named!(pub fun_name<OutputType>, ...)`
+- `named!` now handles the alternative `named!(pub fun_name<OutputType>, ...)`
### Fixed
- `filter!` now returns the whole input if the filter function never returned false
diff --git a/Cargo.toml b/Cargo.toml
index 1a14020..6e38fa0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "nom"
-version = "7.0.0"
+version = "7.1.0"
authors = ["contact@geoffroycouprie.com"]
include = ["CHANGELOG.md", "LICENSE", "README.md", ".gitignore", "Cargo.toml", "src/*.rs", "src/*/*.rs", "tests/*.rs", "doc/nom_recipes.md", "build.rs"]
autoexamples = false
@@ -31,15 +31,16 @@ lto = true
codegen-units = 1
debug = true
-[lib]
-bench = false
-
[[example]]
name = "json"
path = "examples/json.rs"
required-features = ["alloc"]
[[example]]
+name = "iterator"
+path = "examples/iterator.rs"
+
+[[example]]
name = "s_expression"
path = "examples/s_expression.rs"
required-features = ["alloc"]
@@ -57,9 +58,6 @@ name = "arithmetic_ast"
required-features = ["alloc"]
[[test]]
-name = "blockbuf-arithmetic"
-
-[[test]]
name = "css"
[[test]]
@@ -100,51 +98,16 @@ name = "reborrow_fold"
[[test]]
name = "fnmut"
required-features = ["alloc"]
-
-[[bench]]
-name = "arithmetic"
-path = "benches/arithmetic.rs"
-harness = false
-
-[[bench]]
-name = "number"
-path = "benches/number.rs"
-harness = false
-
-[[bench]]
-name = "http"
-path = "benches/http.rs"
-harness = false
-
-[[bench]]
-name = "ini"
-path = "benches/ini.rs"
-harness = false
-
-[[bench]]
-name = "ini_str"
-path = "benches/ini_str.rs"
-harness = false
-
-[[bench]]
-name = "json"
-path = "benches/json.rs"
-harness = false
[dependencies.memchr]
-version = "2.0"
+version = "2.3"
default-features = false
[dependencies.minimal-lexical]
-version = "0.1.2"
-[dev-dependencies.criterion]
-version = "0.3"
-
+version = "0.2.0"
+default-features = false
[dev-dependencies.doc-comment]
version = "0.3"
-[dev-dependencies.jemallocator]
-version = "^0.3"
-
[dev-dependencies.proptest]
version = "1.0.0"
[build-dependencies.version_check]
@@ -154,7 +117,7 @@ version = "0.9"
alloc = []
default = ["std"]
docsrs = []
-std = ["alloc", "memchr/use_std"]
+std = ["alloc", "memchr/std", "minimal-lexical/std"]
[badges.coveralls]
branch = "master"
repository = "Geal/nom"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index b2e176a..4e5b011 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,7 +1,7 @@
[package]
name = "nom"
-version = "7.0.0"
+version = "7.1.0"
authors = [ "contact@geoffroycouprie.com" ]
description = "A byte-oriented, zero-copy, parser combinators library"
license = "MIT"
@@ -28,20 +28,19 @@ include = [
[features]
alloc = []
-std = ["alloc", "memchr/use_std"]
+std = ["alloc", "memchr/std", "minimal-lexical/std"]
default = ["std"]
docsrs = []
-[dependencies]
-minimal-lexical = "0.1.2"
+[dependencies.minimal-lexical]
+version = "0.2.0"
+default-features = false
[dependencies.memchr]
-version = "2.0"
+version = "2.3"
default-features = false
[dev-dependencies]
-criterion = "0.3"
-jemallocator = "^0.3"
doc-comment = "0.3"
proptest = "1.0.0"
@@ -57,9 +56,6 @@ debug = true
lto = true
codegen-units = 1
-[lib]
-bench = false
-
[[test]]
name = "arithmetic"
@@ -68,9 +64,6 @@ name = "arithmetic_ast"
required-features = ["alloc"]
[[test]]
-name = "blockbuf-arithmetic"
-
-[[test]]
name = "css"
[[test]]
@@ -112,43 +105,14 @@ name = "reborrow_fold"
name = "fnmut"
required-features = ["alloc"]
-[[bench]]
-name = "arithmetic"
-path = "benches/arithmetic.rs"
-harness = false
-
-[[bench]]
-name = "number"
-path = "benches/number.rs"
-harness = false
-
-[[bench]]
-name = "http"
-path = "benches/http.rs"
-harness = false
-
-[[bench]]
-name = "ini"
-path = "benches/ini.rs"
-harness = false
-
-[[bench]]
-name = "ini_str"
-path = "benches/ini_str.rs"
-harness = false
-
-[[bench]]
-name = "json"
-path = "benches/json.rs"
-harness = false
-
[[example]]
name = "json"
required-features = ["alloc"]
path = "examples/json.rs"
-#[[example]]
-#name = "iterator"
+[[example]]
+name = "iterator"
+path = "examples/iterator.rs"
[[example]]
name = "s_expression"
@@ -164,3 +128,6 @@ path = "examples/string.rs"
travis-ci = { repository = "Geal/nom" }
coveralls = { repository = "Geal/nom", branch = "master", service = "github" }
maintenance = { status = "actively-developed" }
+
+[workspace]
+members = [".", "benchmarks/"]
diff --git a/METADATA b/METADATA
index c61aba3..504894c 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/nom/nom-7.0.0.crate"
+ value: "https://static.crates.io/crates/nom/nom-7.1.0.crate"
}
- version: "7.0.0"
+ version: "7.1.0"
license_type: NOTICE
last_upgrade_date {
- year: 2021
- month: 9
- day: 23
+ year: 2022
+ month: 3
+ day: 1
}
}
diff --git a/README.md b/README.md
index e1bf4a8..1a95f96 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Join the chat at https://gitter.im/Geal/nom](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Geal/nom?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[![Build Status](https://travis-ci.org/Geal/nom.svg?branch=master)](https://travis-ci.org/Geal/nom)
-[![Coverage Status](https://coveralls.io/repos/Geal/nom/badge.svg?branch=master)](https://coveralls.io/r/Geal/nom?branch=master)
+[![Build Status](https://github.com/Geal/nom/actions/workflows/ci.yml/badge.svg)](https://github.com/Geal/nom/actions/workflows/ci.yml)
+[![Coverage Status](https://coveralls.io/repos/github/Geal/nom/badge.svg?branch=master)](https://coveralls.io/github/Geal/nom?branch=master)
[![Crates.io Version](https://img.shields.io/crates/v/nom.svg)](https://crates.io/crates/nom)
[![Minimum rustc version](https://img.shields.io/badge/rustc-1.48.0+-lightgray.svg)](#rust-version-requirements)
@@ -248,7 +248,9 @@ Here is a (non exhaustive) list of known projects using nom:
[Elm](https://github.com/cout970/Elm-interpreter),
[SystemVerilog](https://github.com/dalance/sv-parser),
[Turtle](https://github.com/vandenoever/rome/tree/master/src/io/turtle),
-[CSML](https://github.com/CSML-by-Clevy/csml-interpreter)
+[CSML](https://github.com/CSML-by-Clevy/csml-interpreter),
+[Wasm](https://github.com/Strytyp/wasm-nom),
+[Pseudocode](https://github.com/Gungy2/pseudocode)
- Interface definition formats: [Thrift](https://github.com/thehydroimpulse/thrust)
- Audio, video and image formats:
[GIF](https://github.com/Geal/gif.rs),
diff --git a/src/bits/complete.rs b/src/bits/complete.rs
index e9ad81a..b46bc7a 100644
--- a/src/bits/complete.rs
+++ b/src/bits/complete.rs
@@ -50,7 +50,7 @@ where
ErrorKind::Eof,
)))
} else {
- let mut acc: O = (0 as u8).into();
+ let mut acc: O = 0_u8.into();
let mut offset: usize = bit_offset;
let mut remaining: usize = count;
let mut end_offset: usize = 0;
diff --git a/src/bits/streaming.rs b/src/bits/streaming.rs
index 700b903..e8adc1c 100644
--- a/src/bits/streaming.rs
+++ b/src/bits/streaming.rs
@@ -24,7 +24,7 @@ where
if input.input_len() * 8 < count + bit_offset {
Err(Err::Incomplete(Needed::new(count as usize)))
} else {
- let mut acc: O = (0 as u8).into();
+ let mut acc: O = 0_u8.into();
let mut offset: usize = bit_offset;
let mut remaining: usize = count;
let mut end_offset: usize = 0;
@@ -78,3 +78,52 @@ where
})
}
}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_take_0() {
+ let input = [].as_ref();
+ let count = 0usize;
+ assert_eq!(count, 0usize);
+ let offset = 0usize;
+
+ let result: crate::IResult<(&[u8], usize), usize> = take(count)((input, offset));
+
+ assert_eq!(result, Ok(((input, offset), 0)));
+ }
+
+ #[test]
+ fn test_tag_ok() {
+ let input = [0b00011111].as_ref();
+ let offset = 0usize;
+ let bits_to_take = 4usize;
+ let value_to_tag = 0b0001;
+
+ let result: crate::IResult<(&[u8], usize), usize> =
+ tag(value_to_tag, bits_to_take)((input, offset));
+
+ assert_eq!(result, Ok(((input, bits_to_take), value_to_tag)));
+ }
+
+ #[test]
+ fn test_tag_err() {
+ let input = [0b00011111].as_ref();
+ let offset = 0usize;
+ let bits_to_take = 4usize;
+ let value_to_tag = 0b1111;
+
+ let result: crate::IResult<(&[u8], usize), usize> =
+ tag(value_to_tag, bits_to_take)((input, offset));
+
+ assert_eq!(
+ result,
+ Err(crate::Err::Error(crate::error::Error {
+ input: (input, offset),
+ code: ErrorKind::TagBits
+ }))
+ );
+ }
+}
diff --git a/src/branch/mod.rs b/src/branch/mod.rs
index 902d4e8..9df5a29 100644
--- a/src/branch/mod.rs
+++ b/src/branch/mod.rs
@@ -46,7 +46,7 @@ pub trait Alt<I, O, E> {
/// like this: `alt(parser_a, alt(parser_b, parser_c))`
///
/// ```rust
-/// # #[macro_use] extern crate nom;
+/// # use nom::error_position;
/// # use nom::{Err,error::ErrorKind, Needed, IResult};
/// use nom::character::complete::{alpha1, digit1};
/// use nom::branch::alt;
@@ -89,7 +89,6 @@ pub trait Permutation<I, O, E> {
/// tuple of the parser results.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::{Error, ErrorKind}, Needed, IResult};
/// use nom::character::complete::{alpha1, digit1};
/// use nom::branch::permutation;
@@ -183,6 +182,15 @@ macro_rules! alt_trait_inner(
alt_trait!(A B C D E F G H I J K L M N O P Q R S T U);
+// Manually implement Alt for (A,), the 1-tuple type
+impl<Input, Output, Error: ParseError<Input>, A: Parser<Input, Output, Error>>
+ Alt<Input, Output, Error> for (A,)
+{
+ fn choice(&mut self, input: Input) -> IResult<Input, Output, Error> {
+ self.0.parse(input)
+ }
+}
+
macro_rules! permutation_trait(
(
$name1:ident $ty1:ident $item1:ident
diff --git a/src/bytes/complete.rs b/src/bytes/complete.rs
index 8a0c88b..9375b1f 100644
--- a/src/bytes/complete.rs
+++ b/src/bytes/complete.rs
@@ -18,7 +18,6 @@ use crate::traits::{
/// It will return `Err(Err::Error((_, ErrorKind::Tag)))` if the input doesn't match the pattern
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::tag;
///
@@ -59,7 +58,6 @@ where
/// It will return `Err(Err::Error((_, ErrorKind::Tag)))` if the input doesn't match the pattern.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::tag_no_case;
///
@@ -104,7 +102,6 @@ where
/// It will return a `Err::Error(("", ErrorKind::IsNot))` if the pattern wasn't met.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::is_not;
///
@@ -138,7 +135,6 @@ where
/// It will return a `Err(Err::Error((_, ErrorKind::IsA)))` if the pattern wasn't met.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::is_a;
///
@@ -171,7 +167,6 @@ where
/// takes the input and returns a bool)*.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::complete::take_while;
/// use nom::character::is_alphabetic;
@@ -203,7 +198,6 @@ where
/// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::take_while1;
/// use nom::character::is_alphabetic;
@@ -238,7 +232,6 @@ where
/// of range (m <= len <= n).
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::take_while_m_n;
/// use nom::character::is_alphabetic;
@@ -322,7 +315,6 @@ where
/// takes the input and returns a bool)*.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::complete::take_till;
///
@@ -354,7 +346,6 @@ where
/// predicate matches the first input.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::take_till1;
///
@@ -385,7 +376,6 @@ where
/// It will return `Err(Err::Error((_, ErrorKind::Eof)))` if the input is shorter than the argument.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::take;
///
@@ -418,7 +408,6 @@ where
/// if the pattern wasn't met.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::take_until;
///
@@ -454,7 +443,6 @@ where
/// if the pattern wasn't met.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::complete::take_until1;
///
@@ -493,7 +481,6 @@ where
/// * The third argument matches the escaped characters
/// # Example
/// ```
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// # use nom::character::complete::digit1;
/// use nom::bytes::complete::escaped;
@@ -597,7 +584,6 @@ where
/// As an example, the chain `abc\tdef` could be `abc def` (it also consumes the control character)
///
/// ```
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// # use std::str::from_utf8;
/// use nom::bytes::complete::{escaped_transform, tag};
diff --git a/src/bytes/streaming.rs b/src/bytes/streaming.rs
index 8deac13..e972760 100644
--- a/src/bytes/streaming.rs
+++ b/src/bytes/streaming.rs
@@ -16,7 +16,6 @@ use crate::traits::{
/// the input that matches the argument.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::streaming::tag;
///
@@ -58,7 +57,6 @@ where
/// the input that matches the argument with no regard to case.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::streaming::tag_no_case;
///
@@ -104,7 +102,6 @@ where
/// It will return a `Err::Incomplete(Needed::new(1))` if the pattern wasn't met.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::streaming::is_not;
///
@@ -140,7 +137,6 @@ where
/// or if the pattern reaches the end of the input.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::streaming::is_a;
///
@@ -176,7 +172,6 @@ where
/// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern reaches the end of the input.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::streaming::take_while;
/// use nom::character::is_alphabetic;
@@ -212,7 +207,6 @@ where
///
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::streaming::take_while1;
/// use nom::character::is_alphabetic;
@@ -249,7 +243,6 @@ where
///
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::streaming::take_while_m_n;
/// use nom::character::is_alphabetic;
@@ -335,7 +328,6 @@ where
///
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::streaming::take_till;
///
@@ -368,7 +360,6 @@ where
/// end of input or if there was not match.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::streaming::take_till1;
///
@@ -406,7 +397,6 @@ where
///
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::streaming::take;
///
@@ -441,7 +431,6 @@ where
/// contain the pattern or if the input is smaller than the pattern.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::bytes::streaming::take_until;
///
@@ -481,7 +470,6 @@ where
/// contain the pattern or if the input is smaller than the pattern.
/// # Example
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::bytes::streaming::take_until1;
///
@@ -521,7 +509,6 @@ where
/// * The third argument matches the escaped characters
/// # Example
/// ```
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// # use nom::character::complete::digit1;
/// use nom::bytes::streaming::escaped;
@@ -614,7 +601,6 @@ where
/// As an example, the chain `abc\tdef` could be `abc def` (it also consumes the control character)
///
/// ```
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// # use std::str::from_utf8;
/// use nom::bytes::streaming::{escaped_transform, tag};
@@ -629,7 +615,7 @@ where
/// alt((
/// value("\\", tag("\\")),
/// value("\"", tag("\"")),
-/// value("n", tag("\n")),
+/// value("\n", tag("n")),
/// ))
/// )(input)
/// }
diff --git a/src/combinator/mod.rs b/src/combinator/mod.rs
index a2e59fb..7071cc7 100644
--- a/src/combinator/mod.rs
+++ b/src/combinator/mod.rs
@@ -56,7 +56,6 @@ where
/// Maps a function on the result of a parser.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// use nom::{Err,error::ErrorKind, IResult,Parser};
/// use nom::character::complete::digit1;
/// use nom::combinator::map;
@@ -85,7 +84,6 @@ where
/// Applies a function returning a `Result` over the result of a parser.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// use nom::combinator::map_res;
@@ -124,7 +122,6 @@ where
/// Applies a function returning an `Option` over the result of a parser.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// use nom::combinator::map_opt;
@@ -163,7 +160,6 @@ where
/// Applies a parser over the result of another one.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// use nom::bytes::complete::take;
@@ -195,7 +191,6 @@ where
/// Creates a new parser from the output of the first parser, then apply that parser over the rest of the input.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::bytes::complete::take;
/// use nom::number::complete::u8;
@@ -210,11 +205,11 @@ where
/// ```
pub fn flat_map<I, O1, O2, E: ParseError<I>, F, G, H>(
mut parser: F,
- applied_parser: G,
+ mut applied_parser: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
- G: Fn(O1) -> H,
+ G: FnMut(O1) -> H,
H: Parser<I, O2, E>,
{
move |input: I| {
@@ -226,7 +221,6 @@ where
/// Optional parser: Will return `None` if not successful.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::opt;
/// use nom::character::complete::alpha1;
@@ -257,7 +251,6 @@ where
/// Calls the parser if the condition is met.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, IResult};
/// use nom::combinator::cond;
/// use nom::character::complete::alpha1;
@@ -295,7 +288,6 @@ where
/// Tries to apply its parser without consuming the input.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::peek;
/// use nom::character::complete::alpha1;
@@ -326,7 +318,6 @@ where
/// will succeed
///
/// ```
-/// # #[macro_use] extern crate nom;
/// # use std::str;
/// # use nom::{Err, error::ErrorKind, IResult};
/// # use nom::combinator::eof;
@@ -349,7 +340,6 @@ pub fn eof<I: InputLength + Clone, E: ParseError<I>>(input: I) -> IResult<I, I,
/// Transforms Incomplete into `Error`.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::bytes::streaming::take;
/// use nom::combinator::complete;
@@ -377,7 +367,6 @@ where
/// Succeeds if all the input has been consumed by its child parser.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::all_consuming;
/// use nom::character::complete::alpha1;
@@ -411,7 +400,6 @@ where
/// parser.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::verify;
/// use nom::character::complete::alpha1;
@@ -449,7 +437,6 @@ where
/// Returns the provided value if the child parser succeeds.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::value;
/// use nom::character::complete::alpha1;
@@ -474,7 +461,6 @@ where
/// Succeeds if the child parser returns an error.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::not;
/// use nom::character::complete::alpha1;
@@ -503,7 +489,6 @@ where
/// If the child parser was successful, return the consumed input as produced value.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::recognize;
/// use nom::character::complete::{char, alpha1};
@@ -544,7 +529,6 @@ where
/// Returned tuple is of the format `(consumed input, produced output)`.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::{consumed, value, recognize, map};
/// use nom::character::complete::{char, alpha1};
@@ -594,7 +578,6 @@ where
/// transforms an error to failure
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::combinator::cut;
/// use nom::character::complete::alpha1;
@@ -622,7 +605,6 @@ where
/// as long as the `Into` implementations are available
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// use nom::combinator::into;
/// use nom::character::complete::alpha1;
@@ -753,7 +735,6 @@ enum State<E> {
/// specify the default case.
///
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::branch::alt;
/// use nom::combinator::{success, value};
diff --git a/src/internal.rs b/src/internal.rs
index 762f3d8..8a3c6a1 100644
--- a/src/internal.rs
+++ b/src/internal.rs
@@ -259,7 +259,7 @@ pub trait Parser<I, O, E> {
/// Creates a second parser from the output of the first one, then apply over the rest of the input
fn flat_map<G, H, O2>(self, g: G) -> FlatMap<Self, G, O>
where
- G: Fn(O) -> H,
+ G: FnMut(O) -> H,
H: Parser<I, O2, E>,
Self: core::marker::Sized,
{
diff --git a/src/lib.rs b/src/lib.rs
index 98cd585..1ce115a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -136,13 +136,13 @@
//! A parser in nom is a function which, for an input type `I`, an output type `O`
//! and an optional error type `E`, will have the following signature:
//!
-//! ```rust,ignore
+//! ```rust,compile_fail
//! fn parser(input: I) -> IResult<I, O, E>;
//! ```
//!
//! Or like this, if you don't want to specify a custom error type (it will be `(I, ErrorKind)` by default):
//!
-//! ```rust,ignore
+//! ```rust,compile_fail
//! fn parser(input: I) -> IResult<I, O>;
//! ```
//!
@@ -445,29 +445,21 @@ pub use self::str::*;
#[macro_use]
pub mod error;
-#[macro_use]
+pub mod combinator;
mod internal;
mod traits;
#[macro_use]
-pub mod combinator;
-#[macro_use]
pub mod branch;
-#[macro_use]
-pub mod sequence;
-#[macro_use]
pub mod multi;
+pub mod sequence;
-#[macro_use]
-pub mod bytes;
-#[macro_use]
pub mod bits;
+pub mod bytes;
-#[macro_use]
pub mod character;
mod str;
-#[macro_use]
pub mod number;
#[cfg(feature = "docsrs")]
diff --git a/src/multi/mod.rs b/src/multi/mod.rs
index 9f72888..a119134 100644
--- a/src/multi/mod.rs
+++ b/src/multi/mod.rs
@@ -260,7 +260,6 @@ where
/// * `sep` Parses the separator between list elements.
/// * `f` Parses the elements of the list.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::multi::separated_list1;
/// use nom::bytes::complete::tag;
@@ -332,7 +331,6 @@ where
/// * `n` The maximum number of iterations.
/// * `f` The parser to apply.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::multi::many_m_n;
/// use nom::bytes::complete::tag;
@@ -399,7 +397,6 @@ where
/// # Arguments
/// * `f` The parser to apply.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::multi::many0_count;
/// use nom::bytes::complete::tag;
@@ -452,7 +449,6 @@ where
/// # Arguments
/// * `f` The parser to apply.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::multi::many1_count;
/// use nom::bytes::complete::tag;
@@ -509,7 +505,6 @@ where
/// * `f` The parser to apply.
/// * `count` How often to apply the parser.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::multi::count;
/// use nom::bytes::complete::tag;
@@ -562,7 +557,6 @@ where
/// * `f` The parser to apply.
/// * `buf` The slice to fill
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::multi::fill;
/// use nom::bytes::complete::tag;
@@ -616,7 +610,6 @@ where
/// * `g` The function that combines a result of `f` with
/// the current accumulator.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::multi::fold_many0;
/// use nom::bytes::complete::tag;
@@ -687,7 +680,6 @@ where
/// * `g` The function that combines a result of `f` with
/// the current accumulator.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::multi::fold_many1;
/// use nom::bytes::complete::tag;
@@ -768,7 +760,6 @@ where
/// * `g` The function that combines a result of `f` with
/// the current accumulator.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::multi::fold_many_m_n;
/// use nom::bytes::complete::tag;
@@ -847,7 +838,6 @@ where
/// # Arguments
/// * `f` The parser to apply.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::ErrorKind, Needed, IResult};
/// use nom::number::complete::be_u16;
/// use nom::multi::length_data;
@@ -892,7 +882,6 @@ where
/// * `f` The parser to apply.
/// * `g` The parser to apply on the subslice.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::number::complete::be_u16;
/// use nom::multi::length_value;
@@ -941,7 +930,6 @@ where
/// * `f` The parser to apply to obtain the count.
/// * `g` The parser to apply repeatedly.
/// ```rust
-/// # #[macro_use] extern crate nom;
/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
/// use nom::number::complete::u8;
/// use nom::multi::length_count;
diff --git a/src/number/complete.rs b/src/number/complete.rs
index c5553a4..d23079e 100644
--- a/src/number/complete.rs
+++ b/src/number/complete.rs
@@ -1426,6 +1426,40 @@ where
)(input)
}
+// workaround until issues with minimal-lexical are fixed
+#[doc(hidden)]
+pub fn recognize_float_or_exceptions<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
+where
+ T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
+ T: Clone + Offset,
+ T: InputIter + InputTake + Compare<&'static str>,
+ <T as InputIter>::Item: AsChar,
+ T: InputTakeAtPosition,
+ <T as InputTakeAtPosition>::Item: AsChar,
+{
+ alt((
+ |i: T| {
+ recognize_float::<_, E>(i.clone()).map_err(|e| match e {
+ crate::Err::Error(_) => crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)),
+ crate::Err::Failure(_) => crate::Err::Failure(E::from_error_kind(i, ErrorKind::Float)),
+ crate::Err::Incomplete(needed) => crate::Err::Incomplete(needed),
+ })
+ },
+ |i: T| {
+ crate::bytes::complete::tag_no_case::<_, _, E>("nan")(i.clone())
+ .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
+ },
+ |i: T| {
+ crate::bytes::complete::tag_no_case::<_, _, E>("inf")(i.clone())
+ .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
+ },
+ |i: T| {
+ crate::bytes::complete::tag_no_case::<_, _, E>("infinity")(i.clone())
+ .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
+ },
+ ))(input)
+}
+
/// Recognizes a floating point number in text format and returns the integer, fraction and exponent parts of the input data
///
/// *Complete version*: Can parse until the end of input.
@@ -1444,7 +1478,7 @@ where
let (i, sign) = sign(input.clone())?;
//let (i, zeroes) = take_while(|c: <T as InputTakeAtPosition>::Item| c.as_char() == '0')(i)?;
- let (i, zeroes) = match i.as_bytes().iter().position(|c| *c != b'0' as u8) {
+ let (i, zeroes) = match i.as_bytes().iter().position(|c| *c != b'0') {
Some(index) => i.take_split(index),
None => i.take_split(i.input_len()),
};
@@ -1452,7 +1486,7 @@ where
let (i, mut integer) = match i
.as_bytes()
.iter()
- .position(|c| !(*c >= b'0' as u8 && *c <= b'9' as u8))
+ .position(|c| !(*c >= b'0' && *c <= b'9'))
{
Some(index) => i.take_split(index),
None => i.take_split(i.input_len()),
@@ -1472,8 +1506,8 @@ where
let mut zero_count = 0usize;
let mut position = None;
for (pos, c) in i.as_bytes().iter().enumerate() {
- if *c >= b'0' as u8 && *c <= b'9' as u8 {
- if *c == b'0' as u8 {
+ if *c >= b'0' && *c <= b'9' {
+ if *c == b'0' {
zero_count += 1;
} else {
zero_count = 0;
@@ -1517,6 +1551,8 @@ where
Ok((i, (sign, integer, fraction, exp)))
}
+use crate::traits::ParseTo;
+
/// Recognizes floating point number in text format and returns a f32.
///
/// *Complete version*: Can parse until the end of input.
@@ -1537,7 +1573,7 @@ where
pub fn float<T, E: ParseError<T>>(input: T) -> IResult<T, f32, E>
where
T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
- T: Clone + Offset,
+ T: Clone + Offset + ParseTo<f32> + Compare<&'static str>,
T: InputIter + InputLength + InputTake,
<T as InputIter>::Item: AsChar + Copy,
<T as InputIter>::IterElem: Clone,
@@ -1546,6 +1582,7 @@ where
T: AsBytes,
T: for<'a> Compare<&'a [u8]>,
{
+ /*
let (i, (sign, integer, fraction, exponent)) = recognize_float_parts(input)?;
let mut float: f32 = minimal_lexical::parse_float(
@@ -1558,18 +1595,27 @@ where
}
Ok((i, float))
+ */
+ let (i, s) = recognize_float_or_exceptions(input)?;
+ match s.parse_to() {
+ Some(f) => (Ok((i, f))),
+ None => Err(crate::Err::Error(E::from_error_kind(
+ i,
+ crate::error::ErrorKind::Float,
+ ))),
+ }
}
-/// Recognizes floating point number in text format and returns a f32.
+/// Recognizes floating point number in text format and returns a f64.
///
/// *Complete version*: Can parse until the end of input.
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
-/// use nom::number::complete::float;
+/// use nom::number::complete::double;
///
/// let parser = |s| {
-/// float(s)
+/// double(s)
/// };
///
/// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
@@ -1580,7 +1626,7 @@ where
pub fn double<T, E: ParseError<T>>(input: T) -> IResult<T, f64, E>
where
T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
- T: Clone + Offset,
+ T: Clone + Offset + ParseTo<f64> + Compare<&'static str>,
T: InputIter + InputLength + InputTake,
<T as InputIter>::Item: AsChar + Copy,
<T as InputIter>::IterElem: Clone,
@@ -1589,6 +1635,7 @@ where
T: AsBytes,
T: for<'a> Compare<&'a [u8]>,
{
+ /*
let (i, (sign, integer, fraction, exponent)) = recognize_float_parts(input)?;
let mut float: f64 = minimal_lexical::parse_float(
@@ -1601,6 +1648,15 @@ where
}
Ok((i, float))
+ */
+ let (i, s) = recognize_float_or_exceptions(input)?;
+ match s.parse_to() {
+ Some(f) => (Ok((i, f))),
+ None => Err(crate::Err::Error(E::from_error_kind(
+ i,
+ crate::error::ErrorKind::Float,
+ ))),
+ }
}
#[cfg(test)]
@@ -1608,7 +1664,6 @@ mod tests {
use super::*;
use crate::error::ErrorKind;
use crate::internal::Err;
- use crate::traits::ParseTo;
use proptest::prelude::*;
macro_rules! assert_parse(
@@ -1942,6 +1997,7 @@ mod tests {
"12.34",
"-1.234E-12",
"-1.234e-12",
+ "0.00000000000000000087",
];
for test in test_cases.drain(..) {
@@ -1965,6 +2021,14 @@ mod tests {
recognize_float(remaining_exponent),
Err(Err::Failure(("", ErrorKind::Digit)))
);
+
+ let (_i, nan) = float::<_, ()>("NaN").unwrap();
+ assert!(nan.is_nan());
+
+ let (_i, inf) = float::<_, ()>("inf").unwrap();
+ assert!(inf.is_infinite());
+ let (_i, inf) = float::<_, ()>("infinite").unwrap();
+ assert!(inf.is_infinite());
}
#[test]
@@ -2050,6 +2114,7 @@ mod tests {
);
}
+ #[cfg(feature = "std")]
fn parse_f64(i: &str) -> IResult<&str, f64, ()> {
match recognize_float(i) {
Err(e) => Err(e),
diff --git a/src/number/streaming.rs b/src/number/streaming.rs
index 3ca445f..7c53ccc 100644
--- a/src/number/streaming.rs
+++ b/src/number/streaming.rs
@@ -1395,6 +1395,40 @@ where
)(input)
}
+// workaround until issues with minimal-lexical are fixed
+#[doc(hidden)]
+pub fn recognize_float_or_exceptions<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
+where
+ T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
+ T: Clone + Offset,
+ T: InputIter + InputTake + InputLength + Compare<&'static str>,
+ <T as InputIter>::Item: AsChar,
+ T: InputTakeAtPosition,
+ <T as InputTakeAtPosition>::Item: AsChar,
+{
+ alt((
+ |i: T| {
+ recognize_float::<_, E>(i.clone()).map_err(|e| match e {
+ crate::Err::Error(_) => crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)),
+ crate::Err::Failure(_) => crate::Err::Failure(E::from_error_kind(i, ErrorKind::Float)),
+ crate::Err::Incomplete(needed) => crate::Err::Incomplete(needed),
+ })
+ },
+ |i: T| {
+ crate::bytes::streaming::tag_no_case::<_, _, E>("nan")(i.clone())
+ .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
+ },
+ |i: T| {
+ crate::bytes::streaming::tag_no_case::<_, _, E>("inf")(i.clone())
+ .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
+ },
+ |i: T| {
+ crate::bytes::streaming::tag_no_case::<_, _, E>("infinity")(i.clone())
+ .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
+ },
+ ))(input)
+}
+
/// Recognizes a floating point number in text format and returns the integer, fraction and exponent parts of the input data
///
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data.
@@ -1413,7 +1447,7 @@ where
let (i, sign) = sign(input.clone())?;
//let (i, zeroes) = take_while(|c: <T as InputTakeAtPosition>::Item| c.as_char() == '0')(i)?;
- let (i, zeroes) = match i.as_bytes().iter().position(|c| *c != b'0' as u8) {
+ let (i, zeroes) = match i.as_bytes().iter().position(|c| *c != b'0') {
Some(index) => i.take_split(index),
None => i.take_split(i.input_len()),
};
@@ -1422,7 +1456,7 @@ where
let (i, mut integer) = match i
.as_bytes()
.iter()
- .position(|c| !(*c >= b'0' as u8 && *c <= b'9' as u8))
+ .position(|c| !(*c >= b'0' && *c <= b'9'))
{
Some(index) => i.take_split(index),
None => i.take_split(i.input_len()),
@@ -1442,8 +1476,8 @@ where
let mut zero_count = 0usize;
let mut position = None;
for (pos, c) in i.as_bytes().iter().enumerate() {
- if *c >= b'0' as u8 && *c <= b'9' as u8 {
- if *c == b'0' as u8 {
+ if *c >= b'0' && *c <= b'9' {
+ if *c == b'0' {
zero_count += 1;
} else {
zero_count = 0;
@@ -1512,7 +1546,7 @@ pub fn float<T, E: ParseError<T>>(input: T) -> IResult<T, f32, E>
where
T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
- T: InputIter + InputLength + InputTake + crate::traits::ParseTo<i32>,
+ T: InputIter + InputLength + InputTake + crate::traits::ParseTo<f32> + Compare<&'static str>,
<T as InputIter>::Item: AsChar,
<T as InputIter>::IterElem: Clone,
T: InputTakeAtPosition,
@@ -1520,6 +1554,7 @@ where
T: AsBytes,
T: for<'a> Compare<&'a [u8]>,
{
+ /*
let (i, (sign, integer, fraction, exponent)) = recognize_float_parts(input)?;
let mut float: f32 = minimal_lexical::parse_float(
@@ -1532,19 +1567,28 @@ where
}
Ok((i, float))
+ */
+ let (i, s) = recognize_float_or_exceptions(input)?;
+ match s.parse_to() {
+ Some(f) => (Ok((i, f))),
+ None => Err(crate::Err::Error(E::from_error_kind(
+ i,
+ crate::error::ErrorKind::Float,
+ ))),
+ }
}
-/// Recognizes floating point number in text format and returns a f32.
+/// Recognizes floating point number in text format and returns a f64.
///
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data.
///
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
-/// use nom::number::complete::float;
+/// use nom::number::complete::double;
///
/// let parser = |s| {
-/// float(s)
+/// double(s)
/// };
///
/// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
@@ -1556,7 +1600,7 @@ pub fn double<T, E: ParseError<T>>(input: T) -> IResult<T, f64, E>
where
T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
T: Clone + Offset,
- T: InputIter + InputLength + InputTake + crate::traits::ParseTo<i32>,
+ T: InputIter + InputLength + InputTake + crate::traits::ParseTo<f64> + Compare<&'static str>,
<T as InputIter>::Item: AsChar,
<T as InputIter>::IterElem: Clone,
T: InputTakeAtPosition,
@@ -1564,6 +1608,7 @@ where
T: AsBytes,
T: for<'a> Compare<&'a [u8]>,
{
+ /*
let (i, (sign, integer, fraction, exponent)) = recognize_float_parts(input)?;
let mut float: f64 = minimal_lexical::parse_float(
@@ -1576,6 +1621,15 @@ where
}
Ok((i, float))
+ */
+ let (i, s) = recognize_float_or_exceptions(input)?;
+ match s.parse_to() {
+ Some(f) => (Ok((i, f))),
+ None => Err(crate::Err::Error(E::from_error_kind(
+ i,
+ crate::error::ErrorKind::Float,
+ ))),
+ }
}
#[cfg(test)]
@@ -1583,7 +1637,6 @@ mod tests {
use super::*;
use crate::error::ErrorKind;
use crate::internal::{Err, Needed};
- use crate::traits::ParseTo;
use proptest::prelude::*;
macro_rules! assert_parse(
@@ -2023,6 +2076,7 @@ mod tests {
"12.34",
"-1.234E-12",
"-1.234e-12",
+ "0.00000000000000000087",
];
for test in test_cases.drain(..) {
@@ -2046,6 +2100,14 @@ mod tests {
recognize_float(remaining_exponent),
Err(Err::Incomplete(Needed::new(1)))
);
+
+ let (_i, nan) = float::<_, ()>("NaN").unwrap();
+ assert!(nan.is_nan());
+
+ let (_i, inf) = float::<_, ()>("inf").unwrap();
+ assert!(inf.is_infinite());
+ let (_i, inf) = float::<_, ()>("infinite").unwrap();
+ assert!(inf.is_infinite());
}
#[test]
@@ -2131,7 +2193,9 @@ mod tests {
);
}
+ #[cfg(feature = "std")]
fn parse_f64(i: &str) -> IResult<&str, f64, ()> {
+ use crate::traits::ParseTo;
match recognize_float(i) {
Err(e) => Err(e),
Ok((i, s)) => {
diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs
index bf5dcfd..100c63f 100644
--- a/src/sequence/mod.rs
+++ b/src/sequence/mod.rs
@@ -12,6 +12,7 @@ use crate::internal::{IResult, Parser};
/// # Arguments
/// * `first` The first parser to apply.
/// * `second` The second parser to apply.
+///
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
@@ -45,6 +46,7 @@ where
/// # Arguments
/// * `first` The opening parser.
/// * `second` The second parser to get object.
+///
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
@@ -78,6 +80,7 @@ where
/// # Arguments
/// * `first` The first parser to apply.
/// * `second` The second parser to match an object.
+///
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
@@ -113,6 +116,7 @@ where
/// * `first` The first parser to apply.
/// * `sep` The separator parser to apply.
/// * `second` The second parser to apply.
+///
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
@@ -151,6 +155,7 @@ where
/// * `first` The first parser to apply and discard.
/// * `second` The second parser to apply.
/// * `third` The third parser to apply and discard.
+///
/// ```rust
/// # use nom::{Err, error::ErrorKind, Needed};
/// # use nom::Needed::Size;
diff --git a/src/str.rs b/src/str.rs
index e8d38c6..1a8b8ba 100644
--- a/src/str.rs
+++ b/src/str.rs
@@ -88,7 +88,7 @@ mod test {
);
assert!(
output == CONSUMED,
- "Parser `take_s` doens't return the string it consumed on success. Expected `{}`, got `{}`.",
+ "Parser `take_s` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
CONSUMED,
output
);
@@ -120,7 +120,7 @@ mod test {
assert!(
output == CONSUMED,
"Parser `take_until`\
- doens't return the string it consumed on success. Expected `{}`, got `{}`.",
+ doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
CONSUMED,
output
);
@@ -281,7 +281,7 @@ mod test {
);
assert!(
output == CONSUMED,
- "Parser `is_not` doens't return the string it consumed on success. Expected `{}`, got `{}`.",
+ "Parser `is_not` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
CONSUMED,
output
);
@@ -432,7 +432,7 @@ mod test {
);
assert!(
output == CONSUMED,
- "Parser `is_a` doens't return the string it consumed on success. Expected `{}`, got `{}`.",
+ "Parser `is_a` doesn't return the string it consumed on success. Expected `{}`, got `{}`.",
CONSUMED,
output
);
diff --git a/src/traits.rs b/src/traits.rs
index a073fd3..3c3053e 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -701,7 +701,7 @@ impl<'a> InputTakeAtPosition for &'a str {
}
}
-/// Indicates wether a comparison was successful, an error, or
+/// Indicates whether a comparison was successful, an error, or
/// if more data was needed
#[derive(Debug, PartialEq)]
pub enum CompareResult {
diff --git a/tests/blockbuf-arithmetic.rs b/tests/blockbuf-arithmetic.rs
deleted file mode 100644
index 27a295f..0000000
--- a/tests/blockbuf-arithmetic.rs
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
-#[macro_use]
-extern crate nom;
-extern crate bytes;
-
-use nom::{Compare,CompareResult,InputLength,InputIter,Slice,HexDisplay};
-
-use std::str;
-use std::str::FromStr;
-use bytes::{Buf,MutBuf};
-use bytes::buf::{BlockBuf,BlockBufCursor};
-use std::ops::{Range,RangeTo,RangeFrom,RangeFull};
-use std::iter::{Enumerate,Iterator};
-use std::fmt;
-use std::cmp::{min,PartialEq};
-
-#[derive(Clone,Copy)]
-#[repr(C)]
-pub struct BlockSlice<'a> {
- buf: &'a BlockBuf,
- start: usize,
- end: usize,
-}
-
-impl<'a> BlockSlice<'a> {
- fn cursor(&self) -> WrapCursor<'a> {
- let mut cur = self.buf.buf();
- cur.advance(self.start);
- WrapCursor {
- cursor: cur,
- length: self.end - self.start,
- }
- }
-}
-
-impl<'a> fmt::Debug for BlockSlice<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "BlockSlice {{ start: {}, end: {}, data:\n{}\n}}", self.start, self.end, self.buf.bytes().unwrap_or(&b""[..]).to_hex(16))
- }
-}
-
-impl<'a> PartialEq for BlockSlice<'a> {
- fn eq(&self, other: &BlockSlice<'a>) -> bool {
- let bufs = (self.buf as *const BlockBuf) == (other.buf as *const BlockBuf);
- self.start == other.start && self.end == other.end && bufs
- }
-}
-
-impl<'a> Slice<Range<usize>> for BlockSlice<'a> {
- fn slice(&self, range:Range<usize>) -> Self {
- BlockSlice {
- buf: self.buf,
- start: self.start + range.start,
- //FIXME: check for valid end here
- end: self.start + range.end,
- }
- }
-}
-
-impl<'a> Slice<RangeTo<usize>> for BlockSlice<'a> {
- fn slice(&self, range:RangeTo<usize>) -> Self {
- self.slice(0..range.end)
- }
-}
-
-impl<'a> Slice<RangeFrom<usize>> for BlockSlice<'a> {
- fn slice(&self, range:RangeFrom<usize>) -> Self {
- self.slice(range.start..self.end - self.start)
- }
-}
-
-impl<'a> Slice<RangeFull> for BlockSlice<'a> {
- fn slice(&self, _:RangeFull) -> Self {
- BlockSlice {
- buf: self.buf,
- start: self.start,
- end: self.end,
- }
- }
-}
-
-
-impl<'a> InputIter for BlockSlice<'a> {
- type Item = u8;
- type RawItem = u8;
- type Iter = Enumerate<WrapCursor<'a>>;
- type IterElem = WrapCursor<'a>;
-
- fn iter_indices(&self) -> Self::Iter {
- self.cursor().enumerate()
- }
- fn iter_elements(&self) -> Self::IterElem {
- self.cursor()
- }
- fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
- self.cursor().position(|b| predicate(b))
- }
- fn slice_index(&self, count:usize) -> Option<usize> {
- if self.end - self.start >= count {
- Some(count)
- } else {
- None
- }
- }
-}
-
-
-impl<'a> InputLength for BlockSlice<'a> {
- fn input_len(&self) -> usize {
- self.end - self.start
- }
-}
-
-impl<'a,'b> Compare<&'b[u8]> for BlockSlice<'a> {
- fn compare(&self, t: &'b[u8]) -> CompareResult {
- let len = self.end - self.start;
- let blen = t.len();
- let m = if len < blen { len } else { blen };
- let reduced = self.slice(..m);
- let b = &t[..m];
-
- for (a,b) in reduced.cursor().zip(b.iter()) {
- if a != *b {
- return CompareResult::Error;
- }
- }
- if m < blen {
- CompareResult::Incomplete
- } else {
- CompareResult::Ok
- }
- }
-
-
- #[inline(always)]
- fn compare_no_case(&self, t: &'b[u8]) -> CompareResult {
- let len = self.end - self.start;
- let blen = t.len();
- let m = if len < blen { len } else { blen };
- let reduced = self.slice(..m);
- let other = &t[..m];
-
- if !reduced.cursor().zip(other).all(|(a, b)| {
- match (a,*b) {
- (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == *b,
- (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122 ) |(97...122, 65...90) => {
- a & 0b01000000 == *b & 0b01000000
- }
- _ => false
- }
- }) {
- CompareResult::Error
- } else if m < blen {
- CompareResult::Incomplete
- } else {
- CompareResult::Ok
- }
- }
-}
-
-impl<'a,'b> Compare<&'b str> for BlockSlice<'a> {
- fn compare(&self, t: &'b str) -> CompareResult {
- self.compare(str::as_bytes(t))
- }
- fn compare_no_case(&self, t: &'b str) -> CompareResult {
- self.compare_no_case(str::as_bytes(t))
- }
-}
-
-//Wrapper to implement Iterator on BlockBufCursor
-pub struct WrapCursor<'a> {
- pub cursor: BlockBufCursor<'a>,
- pub length: usize,
-}
-
-impl<'a> Iterator for WrapCursor<'a> {
- type Item = u8;
- fn next(&mut self) -> Option<u8> {
- //println!("NEXT: length={}, remaining={}", self.length, self.cursor.remaining());
- if min(self.length, self.cursor.remaining()) > 0 {
- self.length -=1;
- Some(self.cursor.read_u8())
- } else {
- None
- }
- }
-}
-
-//Reimplement eat_separator instead of fixing iterators
-#[macro_export]
-macro_rules! block_eat_separator (
- ($i:expr, $arr:expr) => (
- {
- use nom::{InputLength,InputIter,Slice};
- if ($i).input_len() == 0 {
- Ok(($i, ($i).slice(0..0)))
- } else {
- match ($i).iter_indices().position(|(_, item)| {
- for (_,c) in ($arr).iter_indices() {
- if *c == item { return false; }
- }
- true
- }) {
- Some(index) => {
- Ok((($i).slice(index..), ($i).slice(..index)))
- },
- None => {
- Ok((($i).slice(($i).input_len()..), $i))
- }
- }
- }
- }
- )
-);
-
-#[macro_export]
-macro_rules! block_named (
- ($name:ident, $submac:ident!( $($args:tt)* )) => (
- fn $name<'a>( i: BlockSlice<'a> ) -> nom::IResult<BlockSlice<'a>, BlockSlice<'a>, u32> {
- $submac!(i, $($args)*)
- }
- );
- ($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
- fn $name<'a>( i: BlockSlice<'a> ) -> nom::IResult<BlockSlice<'a>, $o, u32> {
- $submac!(i, $($args)*)
- }
- );
-);
-
-block_named!(sp, block_eat_separator!(&b" \t\r\n"[..]));
-
-macro_rules! block_ws (
- ($i:expr, $($args:tt)*) => (
- {
- sep!($i, sp, $($args)*)
- }
- )
-);
-
-block_named!(digit, is_a!("0123456789"));
-
-block_named!(parens<i64>, block_ws!(delimited!( tag!("("), expr, tag!(")") )) );
-
-
-block_named!(factor<i64>, alt!(
- map_res!(
- block_ws!(digit),
- to_i64
- )
- | parens
- )
-);
-
-block_named!(term <i64>, do_parse!(
- init: factor >>
- res: fold_many0!(
- pair!(alt!(tag!("*") | tag!("/")), factor),
- init,
- |acc, (op, val): (BlockSlice, i64)| {
- if (op.cursor().next().unwrap() as char) == '*' { acc * val } else { acc / val }
- }
- ) >>
- (res)
- )
-);
-
-block_named!(expr <i64>, do_parse!(
- init: term >>
- res: fold_many0!(
- pair!(alt!(tag!("+") | tag!("-")), term),
- init,
- |acc, (op, val): (BlockSlice, i64)| {
- if (op.cursor().next().unwrap() as char) == '+' { acc + val } else { acc - val }
- }
- ) >>
- (res)
- )
-);
-
-
-fn blockbuf_from(input: &[u8]) -> BlockBuf {
- let mut b = BlockBuf::new(2, 100);
- b.copy_from(input);
- b
-}
-
-
-fn sl<'a>(input: &'a BlockBuf) -> BlockSlice<'a> {
- BlockSlice {
- buf: input,
- start: 0,
- end: input.len(),
- }
-}
-
-fn to_i64<'a>(input: BlockSlice<'a>) -> Result<i64, ()> {
- let v: Vec<u8> = input.cursor().collect();
-
- match str::from_utf8(&v) {
- Err(_) => Err(()),
- Ok(s) => match FromStr::from_str(s) {
- Err(_) => Err(()),
- Ok(i) => Ok(i)
- }
- }
-}
-
-#[test]
-fn factor_test() {
- let a = blockbuf_from(&b"3"[..]);
- println!("calculated: {:?}", factor(sl(&a)));
-}
-
-#[test]
-fn parens_test() {
- let input1 = blockbuf_from(&b" 2* ( 3 + 4 ) "[..]);
- println!("calculated 1: {:?}", expr(sl(&input1)));
- let input2 = blockbuf_from(&b" 2*2 / ( 5 - 1) + 3"[..]);
- println!("calculated 2: {:?}", expr(sl(&input2)));
-}
-*/
diff --git a/tests/issues.rs b/tests/issues.rs
index 79c3493..6df183b 100644
--- a/tests/issues.rs
+++ b/tests/issues.rs
@@ -172,7 +172,7 @@ fn issue_many_m_n_with_zeros() {
use nom::character::complete::char;
use nom::multi::many_m_n;
let mut parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
- assert_eq!(parser("aaa"), Ok(("aaa", vec!())));
+ assert_eq!(parser("aaa"), Ok(("aaa", vec![])));
}
#[test]