diff --git a/crates/winnow-datetime-assert/CHANGELOG.md b/crates/winnow-datetime-assert/CHANGELOG.md
new file mode 100644
index 0000000..76c5f01
--- /dev/null
+++ b/crates/winnow-datetime-assert/CHANGELOG.md
@@ -0,0 +1,10 @@
+## 0.2.0 - 2024-05-04
+* Changed parser signatures to meet winnow 0.7 standards
+* Removed dependency on galvanic-test which was accidentally left over from some initial design experiments.
+* Removed paste dependency which is no longer used.
+
+## 0.1.0 - 2024-12-29
+
+Initial release
+
+* Best efforts to fully cover common specs
diff --git a/crates/winnow-datetime-assert/Cargo.toml b/crates/winnow-datetime-assert/Cargo.toml
index c464f09..3421d49 100644
--- a/crates/winnow-datetime-assert/Cargo.toml
+++ b/crates/winnow-datetime-assert/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "winnow_datetime_assert"
-version = "0.1.0"
+version = "0.2.0"
description = "Testing/Benchmarking winnow-datetime parsers"
keywords = [ "iso8601", "date-time", "parser", "winnow" ]
categories = [ "parser-implementations", "date-and-time" ]
@@ -13,11 +13,9 @@ readme = "README.md"
edition = "2021"
[dependencies]
-winnow_datetime = { path = "../winnow-datetime", version = "0.1.0", features = ["serde"] }
+winnow_datetime = { path = "../winnow-datetime", version = "0.2.0", features = ["serde"] }
libtest-mimic = "0.8.1"
-galvanic-test = "0.2.0"
-winnow = "0.6.20"
-paste = "1.0.15"
+winnow = "0.7"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9.34-deprecated"
diff --git a/crates/winnow-datetime-assert/src/lib.rs b/crates/winnow-datetime-assert/src/lib.rs
index dc503a4..62dc65e 100644
--- a/crates/winnow-datetime-assert/src/lib.rs
+++ b/crates/winnow-datetime-assert/src/lib.rs
@@ -132,11 +132,33 @@ macro_rules! define_format_tests {
(covered, uncovered)
});
- fn parse_input(input: &str) -> Result<$piece_type, String> {
- match terminated($parser, eof).parse_next(&mut input.as_bytes()) {
- Ok(p) => Ok(p),
- Err(e) => Err(format!("Failed to parse {}: {}", input, e)),
- }
+ fn parse_input<'i, Input>(input: &mut Input) -> Result<$piece_type, String>
+ where
+ Input: StreamIsPartial
+ + Stream
+ + Compare<&'i str>
+ + AsBStr
+ + Clone
+ + std::fmt::Display,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ {
+ let o = $parser::>(input).map_err(|e| {
+ format!(
+ "Failed to parse datetime: {}: {}",
+ String::from_utf8_lossy(input.as_bstr()),
+ e.to_string()
+ )
+ })?;
+ let _ = eof::>(input).map_err(|e| {
+ format!(
+ "Remaining input parsing datetime: {}: {}",
+ String::from_utf8_lossy(input.as_bstr()),
+ e.to_string()
+ )
+ })?;
+
+ Ok(o)
}
// Generate a trial for each assertion
@@ -144,7 +166,7 @@ macro_rules! define_format_tests {
let name = format!("parses - {}", assertion.format);
trials.push(Trial::test(name, move || {
// Parse the input
- let result = parse_input(&assertion.input);
+ let result = parse_input(&mut assertion.input.as_str());
// If covered, the result must match the expected value
if result != Ok(assertion.expected) {
@@ -162,7 +184,7 @@ macro_rules! define_format_tests {
let name = format!("rejects - {}", assertion.format);
trials.push(Trial::test(name, move || {
// Parse the input
- let result = parse_input(&assertion.input);
+ let result = parse_input(&mut assertion.input.as_str());
// If not covered, the result must be an error
if result.is_ok() {
diff --git a/crates/winnow-datetime/CHANGELOG.md b/crates/winnow-datetime/CHANGELOG.md
new file mode 100644
index 0000000..4288f47
--- /dev/null
+++ b/crates/winnow-datetime/CHANGELOG.md
@@ -0,0 +1,5 @@
+## 0.2.0 - 2015-05-04
+* Changed `Stream` helper type to `PartialInput` since this name conflicts with the winnow naming scheme and causes confusion.
+* Bumped winnow version to 0.7 and changed parser singatures to match standard winnow parsers
+
+## 0.1.0 - 2014-12-29 - Initial Release
diff --git a/crates/winnow-datetime/Cargo.toml b/crates/winnow-datetime/Cargo.toml
index 041153d..c70adfb 100644
--- a/crates/winnow-datetime/Cargo.toml
+++ b/crates/winnow-datetime/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "winnow_datetime"
-version = "0.1.0"
+version = "0.2.0"
description = "Parsing dates using winnow"
keywords = [ "iso8601", "date-time", "parser", "winnow" ]
categories = [ "parser-implementations", "date-and-time" ]
@@ -13,7 +13,7 @@ readme = "README.md"
edition = "2021"
[dependencies]
-winnow = "0.6.20"
+winnow = "0.7"
chrono = { version = "0.4", default-features = false, optional = true }
time = { version = "0.3.37", default-features = false, optional = true }
num-traits = { version = "0.2", optional = true }
diff --git a/crates/winnow-datetime/src/lib.rs b/crates/winnow-datetime/src/lib.rs
index 66285cc..fc119b8 100644
--- a/crates/winnow-datetime/src/lib.rs
+++ b/crates/winnow-datetime/src/lib.rs
@@ -18,4 +18,4 @@ pub use types::Time;
use winnow::Partial;
/// Type for holding partial data for parsers
-pub type Stream<'i> = Partial<&'i [u8]>;
+pub type PartialInput<'i> = Partial<&'i [u8]>;
diff --git a/crates/winnow-datetime/src/parser.rs b/crates/winnow-datetime/src/parser.rs
index 0a00974..9ce9249 100644
--- a/crates/winnow-datetime/src/parser.rs
+++ b/crates/winnow-datetime/src/parser.rs
@@ -5,252 +5,258 @@
use core::str;
use std::ops::RangeBounds;
-use winnow::ascii::digit1;
+use winnow::ascii::{digit1, Int, Uint};
use winnow::combinator::{alt, trace};
-use winnow::error::{ContextError, ErrMode};
-use winnow::stream::{AsBStr, AsChar, Compare, Stream as InputStream, StreamIsPartial};
+use winnow::error::ParserError;
+use winnow::stream::{AsBStr, AsChar, Compare, Stream, StreamIsPartial};
use winnow::token::{literal, take_while};
-use winnow::{PResult, Parser};
-
+use winnow::Parser;
// UTILITY
/// Exactly 1 digit
-pub fn digit_1<'i, Input>(i: &mut Input) -> PResult
+pub fn digit_1(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("digit_1", move |input: &mut Input| {
take_exact_digits(input, 1)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Exactly 2 digits
-pub fn digit_2<'i, Input>(i: &mut Input) -> PResult
+pub fn digit_2(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("digit_2", move |input: &mut Input| {
take_exact_digits(input, 2)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Exactly 3 digits
-pub fn digit_3<'i, Input>(i: &mut Input) -> PResult
+pub fn digit_3(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("digit_3", move |input: &mut Input| {
take_exact_digits(input, 3)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Exactly 4 digits
-pub fn digit_4<'i, Input>(i: &mut Input) -> PResult
+pub fn digit_4(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("digit_4", move |input: &mut Input| {
take_exact_digits(input, 4)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Exactly 6 digits
-pub fn digit_6<'i, Input>(i: &mut Input) -> PResult
+pub fn digit_6(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("digit_6", move |input: &mut Input| {
take_exact_digits(input, 2)
})
- .parse_next(i)
+ .parse_next(input)
}
-fn take_exact_digits<'i, Input>(i: &mut Input, places: usize) -> PResult
+pub(crate) fn take_exact_digits(
+ input: &mut Input,
+ places: usize,
+) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
- let n = take_while(places, |c: ::Token| {
- AsChar::is_dec_digit(&c.as_char())
- })
- .parse_next(i)?;
+ let n = take_while(places, AsChar::is_dec_digit).parse_next(input)?;
- let s = str::from_utf8(n.as_bstr()).expect("Invalid data, expected UTF-8 string");
+ let n = String::from_utf8_lossy(n.as_bstr());
- let number: u32 = s
- .parse()
- .expect("Invalid string, expected ASCII representation of a number");
+ let n = u32::try_from_dec_uint(n.as_ref()).unwrap();
- Ok(number)
+ Ok(n)
}
-pub fn take_digits<'i, Input>(i: &mut Input) -> PResult
+pub fn take_digits<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("take_digits", move |input: &mut Input| {
- let digits = take_while(1.., |c: ::Token| c.is_dec_digit())
- .parse_next(input)?;
+ let out = take_while(1.., AsChar::is_dec_digit).parse_next(input)?;
+ let out = String::from_utf8_lossy(out.as_bstr());
+ let out = u32::try_from_dec_uint(out.as_ref()).unwrap();
- if digits.as_bstr().is_empty() {
- return Err(ErrMode::Backtrack(ContextError::new()));
- }
-
- let s = str::from_utf8(digits.as_bstr()).expect("Invalid data, expected UTF-8 string");
- let res = s
- .parse()
- .expect("Invalid string, expected ASCII representation of a number");
-
- Ok(res)
+ Ok(out)
})
- .parse_next(i)
+ .parse_next(input)
}
-pub fn take_digits_in_range<'i, Input>(
- i: &mut Input,
+pub fn take_digits_in_range(
+ input: &mut Input,
places: usize,
range: impl RangeBounds,
-) -> PResult
+) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
- let n = take_while(places, |c: ::Token| {
- c.as_char().is_digit(10)
- })
- .parse_next(i)?;
-
- let s = str::from_utf8(n.as_bstr()).expect("Invalid data, expected UTF-8 string");
+ let out = take_while(places, AsChar::is_dec_digit).parse_next(input)?;
+ let out = String::from_utf8_lossy(out.as_bstr());
+ let out = u32::try_from_dec_uint(out.as_ref()).unwrap();
- let number: u32 = s
- .parse()
- .expect("Invalid string, expected ASCII representation of a number");
-
- if range.contains(&number) {
- Ok(number)
+ if range.contains(&out) {
+ Ok(out)
} else {
- return Err(ErrMode::Backtrack(ContextError::new()));
+ Err(ParserError::from_input(input))
}
}
-pub fn sign<'i, Input>(i: &mut Input) -> PResult
+pub fn sign<'a, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'a str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
- alt((literal("-"), literal("+")))
- .map(|s: ::Slice| match s.as_bstr() {
- b"-" => -1,
- _ => 1,
- })
- .parse_next(i)
+ trace("sign", move |input: &mut Input| {
+ let i = alt((literal("-"), literal("+")))
+ .map(|s: ::Slice| match s.as_bstr() {
+ b"-" => "-1",
+ _ => "1",
+ })
+ .parse_next(input)?;
+
+ Ok(i32::try_from_dec_int(i).unwrap())
+ })
+ .parse_next(input)
}
// DATE
// MM
-pub fn date_month<'i, Input>(i: &mut Input) -> PResult
+pub fn date_month(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_month", move |input: &mut Input| {
take_digits_in_range(input, 2, 1..=12)
})
- .parse_next(i)
+ .parse_next(input)
}
// DD
-pub fn date_day<'i, Input>(i: &mut Input) -> PResult
+pub fn date_day(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_day", move |input: &mut Input| {
take_digits_in_range(input, 2, 1..=31)
})
- .parse_next(i)
+ .parse_next(input)
}
// TIME
// HH
-pub fn time_hour<'i, Input>(i: &mut Input) -> PResult
+pub fn time_hour(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("time_hour", move |input: &mut Input| {
take_digits_in_range(input, 2, 0..=23)
})
- .parse_next(i)
+ .parse_next(input)
}
// MM
-pub fn time_minute<'i, Input>(i: &mut Input) -> PResult
+pub fn time_minute(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("time_minute", move |input: &mut Input| {
take_digits_in_range(input, 2, 0..=59)
})
- .parse_next(i)
+ .parse_next(input)
}
// SS
-pub fn time_second<'i, Input>(i: &mut Input) -> PResult
+pub fn time_second(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("time_second", move |input: &mut Input| {
take_digits_in_range(input, 2, 0..=60)
})
- .parse_next(i)
+ .parse_next(input)
}
// Converts the fractional part if-any of a number of seconds to milliseconds
// truncating towards zero if there are more than three digits.
// e.g. "" -> 0, "1" -> 100, "12" -> 120, "123" -> 123, "1234" -> 123
-pub fn fraction_millisecond<'i, Input>(i: &mut Input) -> PResult
+pub fn fraction_millisecond<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream,
+ ::Slice: AsBStr,
+ ::Token: AsChar,
+
+ Error: ParserError,
{
trace("fraction_millisecond", move |input: &mut Input| {
let d = digit1(input)?;
let mut digits = d.as_bstr();
let mut l = digits.len();
+
if l > 3 {
digits = digits.get(0..3).unwrap();
}
+
let mut result = 0;
+
if l > 0 {
let digits = str::from_utf8(digits).unwrap(); // This can't panic, `digits` will only include digits.
result = digits.parse().unwrap();
@@ -259,7 +265,8 @@ where
result *= 10;
l += 1;
}
+
Ok(result)
})
- .parse_next(i)
+ .parse_next(input)
}
diff --git a/crates/winnow-datetime/src/types.rs b/crates/winnow-datetime/src/types.rs
index 47fa4cb..56a98af 100644
--- a/crates/winnow-datetime/src/types.rs
+++ b/crates/winnow-datetime/src/types.rs
@@ -104,7 +104,7 @@ pub struct Time {
}
impl Time {
- /// Change this time's offset offset.
+ /// Change this time's offset.
///
/// # Arguments
///
diff --git a/crates/winnow-datetime/tests/lib.rs b/crates/winnow-datetime/tests/lib.rs
deleted file mode 100644
index 8b13789..0000000
--- a/crates/winnow-datetime/tests/lib.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/crates/winnow-iso8601/CHANGELOG.md b/crates/winnow-iso8601/CHANGELOG.md
index 92029a5..c9afe4e 100644
--- a/crates/winnow-iso8601/CHANGELOG.md
+++ b/crates/winnow-iso8601/CHANGELOG.md
@@ -1,5 +1,8 @@
# Changelog
+## 0.5.0 - 2024-05-04
+* Changed parser signatures to meet winnow 0.7 standards
+
## 0.4.0 - 2014-12-29
* Moved Date, Time, and DateTime, Timezone to the `winnow-datetime` so that upcoming format crates
can re-use them. This crate will no longer export these directly, since this caused several type
diff --git a/crates/winnow-iso8601/Cargo.toml b/crates/winnow-iso8601/Cargo.toml
index 80947d0..73c2dfc 100644
--- a/crates/winnow-iso8601/Cargo.toml
+++ b/crates/winnow-iso8601/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "winnow_iso8601"
-version = "0.4.0"
+version = "0.5.0"
description = "Parsing ISO8601 dates using winnow"
keywords = [ "iso8601", "date-time", "parser", "winnow" ]
categories = [ "parser-implementations", "date-and-time" ]
@@ -13,15 +13,15 @@ readme = "README.md"
edition = "2021"
[dependencies]
-winnow = { version = "0.6.20"}
-winnow_datetime = { path = "../winnow-datetime", features = ["serde"], version = "0.1.0" }
+winnow = { version = "0.7" }
+winnow_datetime = { path = "../winnow-datetime", features = ["serde"], version = "0.2.0" }
chrono = { version = "0.4", default-features = false, optional = true }
time = { version = "0.3.37", default-features = false, optional = true }
num-traits = { version = "0.2", optional = true }
serde = { version = "1.0.217", features = ["derive"], optional = true }
[dev-dependencies ]
-winnow_datetime_assert = { path = "../winnow-datetime-assert", version = "0.1.0" }
+winnow_datetime_assert = { path = "../winnow-datetime-assert", version = "0.2.0" }
libtest-mimic = "0.8.1"
[[test]]
diff --git a/crates/winnow-iso8601/src/date.rs b/crates/winnow-iso8601/src/date.rs
index 1efa658..41d75b5 100644
--- a/crates/winnow-iso8601/src/date.rs
+++ b/crates/winnow-iso8601/src/date.rs
@@ -1,13 +1,10 @@
-use alloc::string::String;
-use std::str;
use winnow::combinator::separated_pair;
use winnow::combinator::terminated;
use winnow::combinator::{alt, eof, opt, preceded, trace};
-use winnow::error::ContextError;
-use winnow::error::ErrMode;
-use winnow::stream::{AsBStr, AsChar, Compare, Stream as InputStream, StreamIsPartial};
+use winnow::error::{InputError, ParserError};
+use winnow::stream::{AsBStr, AsChar, Compare, Stream, StreamIsPartial};
use winnow::token::literal;
-use winnow::{seq, PResult, Parser};
+use winnow::{seq, Parser, Result};
use winnow_datetime::parser::date_day;
use winnow_datetime::parser::digit_1;
use winnow_datetime::parser::{date_month, digit_4};
@@ -22,12 +19,8 @@ use winnow_datetime::{date_ymd_seq, date_ywd_seq};
/// ```rust
/// let date = winnow_iso8601::parse_date("2015-11-02").unwrap();
/// ```
-pub fn parse_date(mut i: &str) -> Result {
- if let Ok(parsed) = terminated(date, eof).parse_next(&mut i) {
- Ok(parsed)
- } else {
- Err(format!("Failed to parse date: {}", i))
- }
+pub fn parse_date(mut i: &str) -> Result> {
+ terminated(date, eof).parse_next(&mut i)
}
/// Parses a date
@@ -38,60 +31,64 @@ pub fn parse_date(mut i: &str) -> Result {
/// * `2015-W45-01` or `2015W451`
/// * `2015-306` or `2015306`
///
-/// See [`date()`][`crate::date()`] for the supported formats.
-pub fn date<'i, Input>(i: &mut Input) -> PResult
+/// See [`date()`][`mod@crate::date`] for the supported formats.
+pub fn date<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date", move |input: &mut Input| {
alt((date_ywd, date_ymd_numeric, date_yddd, date_ymd)).parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Date separator -
-pub fn date_sep<'i, Input>(i: &mut Input) -> PResult
+pub fn date_sep<'a, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'a str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_sep", move |input: &mut Input| {
literal("-").parse_next(input).map(|_| '-')
})
- .parse_next(i)
+ .parse_next(input)
}
/// Parses 2 digit week of the year within range 01-52
// WW
-fn date_week<'i, Input>(i: &mut Input) -> PResult
+fn date_week<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_week", move |input: &mut Input| {
let _ = preceded(opt(literal("-")), literal("W")).parse_next(input)?; // [-]Ww
week_of_year(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Parses 2 digit week of the year within range 01-52
// WW
-pub(crate) fn week_of_year<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn week_of_year<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
- trace("date_week", move |input: &mut Input| {
+ trace("week_of_year", move |input: &mut Input| {
take_digits_in_range(input, 2, 1..=52)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Verifies an opt value and calls a verification function on Some
@@ -110,26 +107,28 @@ fn verify_day_of_week(day: u32) -> bool {
}
/// Parses 2 digit week of the year within range 01-7
-pub(crate) fn day_of_week<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn day_of_week<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("day_of_week", move |input: &mut Input| {
take_digits_in_range(input, 1, 1..=7)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Parses 2 digit week of the year within range 01-52
/// Parses a date string as ISO 8601 week date.
// YYYY-"W"WW-D
-pub(crate) fn date_ywd<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn date_ywd<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("", move |input: &mut Input| {
date_ywd_seq!(Date::Week {
@@ -141,39 +140,41 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
// [-]D - unverified
/// Parses a year with +/- and will eventually support 6 digit year
// [+/-]YYYY
-pub(crate) fn date_year<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn date_year<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_year", move |input: &mut Input| {
// The sign is optional, but defaults to `+`
- let sign = opt(sign).parse_next(input)?.unwrap_or(1);
+ let sign = opt(sign).parse_next(input)?.unwrap_or(1i32);
- let year = digit_4(input)? as i32;
+ let year = digit_4(input)?;
if year >= 100 && year < 10000 {
- Ok(sign * year)
+ Ok(sign * year as i32)
} else {
- Err(ErrMode::Backtrack(ContextError::new()))
+ Err(ParserError::from_input(input))
}
})
- .parse_next(i)
+ .parse_next(input)
}
-// YYYY-MM-DD
-pub(crate) fn date_ymd<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn date_ymd<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
+ // YYYY-MM-DD
{
trace("date_ymd", move |input: &mut Input| {
date_ymd_seq!(Date::YMD {
@@ -183,43 +184,46 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
// ordinal DDD
-pub(crate) fn date_day_of_year<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn date_day_of_year<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_day_of_year", move |input: &mut Input| {
take_digits_in_range(input, 3, 1..=366)
})
- .parse_next(i)
+ .parse_next(input)
}
// YYYY-DDD
-pub(crate) fn date_yddd<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn date_yddd<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_yddd", move |input: &mut Input| {
separated_pair(date_year, opt(literal("-")), date_day_of_year)
.map(|(year, day)| Date::Ordinal { year, day })
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Parses a date string specificed as YYYYMMDD
-pub(crate) fn date_ymd_numeric<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn date_ymd_numeric<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("date_ymd_numeric", move |input: &mut Input| {
seq!(Date::YMD {
@@ -229,93 +233,98 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
#[cfg(test)]
mod parsers {
use crate::date::{date, date_yddd, date_year, date_ywd, day_of_week};
- use winnow::stream::AsBStr;
+ use winnow::error::InputError;
+
use winnow::Parser;
use winnow_datetime::parser::{date_day, date_month};
- use winnow_datetime::Stream;
+ use winnow_datetime::PartialInput;
#[test]
fn test_date_year() {
- assert_eq!(date_year(&mut "2015".as_bstr()).unwrap(), 2015);
- assert_eq!(date_year(&mut "+2015".as_bstr()).unwrap(), 2015);
- assert!(date_year(&mut "-333".as_bstr()).is_err());
- assert_eq!(date_year(&mut "-0333".as_bstr()).unwrap(), -333);
- assert_eq!(date_year(&mut "2015-".as_bstr()).unwrap(), 2015);
- assert!(date_year(&mut Stream::new(b"abcd")).is_err());
- assert!(date_year(&mut Stream::new(b"2a03")).is_err());
+ assert_eq!(date_year::<_, InputError<_>>(&mut "2015").unwrap(), 2015);
+ assert_eq!(date_year::<_, InputError<_>>(&mut "+2015").unwrap(), 2015);
+ assert!(date_year::<_, InputError<_>>(&mut "-333").is_err());
+ assert_eq!(date_year::<_, InputError<_>>(&mut "-0333").unwrap(), -333);
+ assert_eq!(date_year::<_, InputError<_>>(&mut "2015-").unwrap(), 2015);
+ assert!(date_year::<_, InputError<_>>(&mut PartialInput::new(b"abcd")).is_err());
+ assert!(date_year::<_, InputError<_>>(&mut PartialInput::new(b"2a03")).is_err());
}
#[test]
fn test_date_month() {
- assert_eq!(date_month(&mut "01".as_bstr()).unwrap(), 1);
- assert_eq!(date_month(&mut "06".as_bstr()).unwrap(), 6);
- assert_eq!(date_month(&mut "12".as_bstr()).unwrap(), 12);
- assert_eq!(date_month(&mut "12-".as_bstr()).unwrap(), 12);
+ assert_eq!(date_month::<_, InputError<_>>(&mut "01").unwrap(), 1);
+ assert_eq!(date_month::<_, InputError<_>>(&mut "06").unwrap(), 6);
+ assert_eq!(date_month::<_, InputError<_>>(&mut "12").unwrap(), 12);
+ assert_eq!(date_month::<_, InputError<_>>(&mut "12-").unwrap(), 12);
- assert!(date_month(&mut Stream::new(b"13\n")).is_err());
- assert!(date_month(&mut Stream::new(b"00\n")).is_err());
+ assert!(date_month::<_, InputError<_>>(&mut PartialInput::new(b"13\n")).is_err());
+ assert!(date_month::<_, InputError<_>>(&mut PartialInput::new(b"00\n")).is_err());
}
#[test]
fn test_date_day() {
- assert_eq!(date_day(&mut "01".as_bstr()).unwrap(), 1);
- assert_eq!(date_day(&mut "12".as_bstr()).unwrap(), 12);
- assert_eq!(date_day(&mut "20".as_bstr()).unwrap(), 20);
- assert_eq!(date_day(&mut "28".as_bstr()).unwrap(), 28);
- assert_eq!(date_day(&mut "30".as_bstr()).unwrap(), 30);
- assert_eq!(date_day(&mut "31".as_bstr()).unwrap(), 31);
- assert_eq!(date_day(&mut "31-".as_bstr()).unwrap(), 31);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "01").unwrap(), 1);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "12").unwrap(), 12);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "20").unwrap(), 20);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "28").unwrap(), 28);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "30").unwrap(), 30);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "31").unwrap(), 31);
+ assert_eq!(date_day::<_, InputError<_>>(&mut "31-").unwrap(), 31);
- assert!(date_day(&mut Stream::new(b"00")).is_err());
- assert!(date_day(&mut Stream::new(b"32")).is_err());
+ assert!(date_day::<_, InputError<_>>(&mut PartialInput::new(b"00")).is_err());
+ assert!(date_day::<_, InputError<_>>(&mut PartialInput::new(b"32")).is_err());
}
#[test]
fn test_date() {
- assert!(date(&mut Stream::new(b"201")).is_err());
- assert!(date(&mut Stream::new(b"2015p00p00")).is_err());
- assert!(date(&mut Stream::new(b"pppp")).is_err());
+ assert!(date::<_, InputError<_>>(&mut PartialInput::new(b"201")).is_err());
+ assert!(date::<_, InputError<_>>(&mut PartialInput::new(b"2015p00p00")).is_err());
+ assert!(date::<_, InputError<_>>(&mut PartialInput::new(b"pppp")).is_err());
}
#[test]
fn test_date_iso_week_date() {
- assert!(date_ywd
- .parse_next(&mut Stream::new(b"2015-W06-8"))
+ assert!(date_ywd::<_, InputError<_>>
+ .parse_next(&mut PartialInput::new(b"2015-W06-8"))
+ .is_err());
+ assert!(date_ywd::<_, InputError<_>>
+ .parse_next(&mut PartialInput::new(b"2015-W068"))
+ .is_err());
+ assert!(date_ywd::<_, InputError<_>>
+ .parse_next(&mut PartialInput::new(b"2015-W06-0"))
.is_err());
- assert!(date_ywd.parse_next(&mut Stream::new(b"2015-W068")).is_err());
- assert!(date_ywd
- .parse_next(&mut Stream::new(b"2015-W06-0"))
+ assert!(date_ywd::<_, InputError<_>>
+ .parse_next(&mut PartialInput::new(b"2015-W00-2"))
.is_err());
- assert!(date_ywd
- .parse_next(&mut Stream::new(b"2015-W00-2"))
+ assert!(date_ywd::<_, InputError<_>>
+ .parse_next(&mut PartialInput::new(b"2015-W54-2"))
.is_err());
- assert!(date_ywd
- .parse_next(&mut Stream::new(b"2015-W54-2"))
+ assert!(date_ywd::<_, InputError<_>>
+ .parse_next(&mut PartialInput::new(b"2015-W542"))
.is_err());
- assert!(date_ywd.parse_next(&mut Stream::new(b"2015-W542")).is_err());
}
#[test]
fn test_date_ordinal_date() {
// not valid here either
- assert!(date_yddd(&mut Stream::new(b"2015-400")).is_err());
+ assert!(date_yddd::<_, InputError<_>>(&mut PartialInput::new(b"2015-400")).is_err());
}
#[test]
fn test_day_of_week() {
- assert_eq!(day_of_week(&mut "1".as_bstr()).unwrap(), 1);
- assert_eq!(day_of_week(&mut "7".as_bstr()).unwrap(), 7);
- assert!(day_of_week(&mut "8".as_bstr()).is_err()); // Invalid day
+ assert_eq!(day_of_week::<_, InputError<_>>(&mut "1").unwrap(), 1);
+ assert_eq!(day_of_week::<_, InputError<_>>(&mut "7").unwrap(), 7);
+ assert!(day_of_week::<_, InputError<_>>(&mut "8").is_err()); // Invalid day
}
#[test]
fn disallows_notallowed() {
- assert!(date(&mut Stream::new(b"0000-20-40")).is_err());
+ assert!(date::<_, InputError<_>>(&mut PartialInput::new(b"0000-20-40")).is_err());
}
}
diff --git a/crates/winnow-iso8601/src/datetime.rs b/crates/winnow-iso8601/src/datetime.rs
index 860cdd6..3a29b37 100644
--- a/crates/winnow-iso8601/src/datetime.rs
+++ b/crates/winnow-iso8601/src/datetime.rs
@@ -1,11 +1,11 @@
use crate::date::date;
use crate::time::base_time;
use ::winnow::Parser;
-use alloc::string::String;
-use winnow::combinator::{separated_pair, trace};
-use winnow::stream::{AsBStr, AsChar, Compare, Stream as InputStream, StreamIsPartial};
+use winnow::combinator::{eof, separated_pair, terminated, trace};
+use winnow::error::{InputError, ParserError};
+use winnow::stream::{AsBStr, AsChar, Compare, Stream, StreamIsPartial};
use winnow::token::literal;
-use winnow::PResult;
+use winnow::Result;
use winnow_datetime::DateTime;
/// Parses a datetime string.
@@ -15,12 +15,8 @@ use winnow_datetime::DateTime;
/// ```rust
/// let dt = winnow_iso8601::parse_datetime("2015-11-03T21:56").unwrap();
/// ```
-pub fn parse_datetime(mut i: &str) -> Result {
- if let Ok(parsed) = datetime(&mut i) {
- Ok(parsed)
- } else {
- Err(format!("Failed to parse datetime: {}", i))
- }
+pub fn parse_datetime(mut i: &str) -> Result> {
+ terminated(datetime, eof).parse_next(&mut i)
}
/// Parses a datetime string.
@@ -28,54 +24,56 @@ pub fn parse_datetime(mut i: &str) -> Result {
/// A datetime string is a combination of the valid formats for the date and time,
/// separated by a literal `T`.
// Full ISO8601 datetime
-pub fn datetime<'i, Input>(i: &mut Input) -> PResult
+pub fn datetime<'i, Input, Error>(input: &mut Input) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("datetime", move |input: &mut Input| {
separated_pair(date, literal("T"), base_time)
.map(|(d, t)| DateTime { date: d, time: t })
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
#[cfg(test)]
mod parsers {
use crate::datetime::datetime;
- use winnow_datetime::Stream;
+ use winnow::error::InputError;
+ use winnow_datetime::PartialInput;
#[test]
fn format_equivalence() {
assert_eq!(
- datetime(&mut Stream::new(b"2001-02-03T04:05:06+07:00")),
- datetime(&mut Stream::new(b"20010203T040506+0700"))
+ datetime::<_, InputError<_>>(&mut "2001-02-03T04:05:06+07:00"),
+ datetime::<_, InputError<_>>(&mut "20010203T040506+0700")
);
assert_eq!(
- datetime(&mut Stream::new(b"2001-02-03T04:05:06+07:00")),
- datetime(&mut Stream::new(b"20010203T04:05:06+0700"))
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2001-02-03T04:05:06+07:00")),
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"20010203T04:05:06+0700"))
);
assert_eq!(
- datetime(&mut Stream::new(b"2001-02-03T04:05:00+07:00")),
- datetime(&mut Stream::new(b"20010203T0405+0700"))
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2001-02-03T04:05:00+07:00")),
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"20010203T0405+0700"))
);
assert_eq!(
- datetime(&mut Stream::new(b"20010203T0405+0700")),
- datetime(&mut Stream::new(b"2001-02-03T0405+0700"))
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"20010203T0405+0700")),
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2001-02-03T0405+0700"))
);
assert_eq!(
- datetime(&mut Stream::new(b"20010203T040506+0700")),
- datetime(&mut Stream::new(b"2001-02-03T040506+0700"))
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"20010203T040506+0700")),
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2001-02-03T040506+0700"))
);
assert_eq!(
- datetime(&mut Stream::new(b"20010203T040506+0000")),
- datetime(&mut Stream::new(b"20010203T040506Z"))
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"20010203T040506+0000")),
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"20010203T040506Z"))
);
assert_eq!(
- datetime(&mut Stream::new(b"2015W056T04:05:06+07:00")),
- datetime(&mut Stream::new(b"2015-W05-6T04:05:06+07:00"))
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2015W056T04:05:06+07:00")),
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2015-W05-6T04:05:06+07:00"))
);
}
@@ -84,13 +82,16 @@ mod parsers {
let test_datetimes = vec!["ppp", "dumd-di-duTmd:iu:m"];
for iso_string in test_datetimes {
- let res = datetime(&mut Stream::new(iso_string.as_bytes()));
+ let res = datetime::<_, InputError<_>>(&mut PartialInput::new(iso_string.as_bytes()));
assert!(res.is_err());
}
}
#[test]
fn disallows_notallowed() {
- assert!(datetime(&mut Stream::new(b"2001-w05-6t04:05:06.123z")).is_err());
+ assert!(
+ datetime::<_, InputError<_>>(&mut PartialInput::new(b"2001-w05-6t04:05:06.123z"))
+ .is_err()
+ );
}
}
diff --git a/crates/winnow-iso8601/src/duration.rs b/crates/winnow-iso8601/src/duration.rs
index f80a0f1..6a1e2fd 100644
--- a/crates/winnow-iso8601/src/duration.rs
+++ b/crates/winnow-iso8601/src/duration.rs
@@ -1,9 +1,9 @@
-use alloc::string::String;
use core::str;
-use winnow::combinator::{opt, preceded, trace};
-use winnow::stream::{AsBStr, AsChar, Compare, Stream as InputStream, StreamIsPartial};
+use winnow::combinator::{eof, opt, preceded, terminated, trace};
+use winnow::error::{InputError, ParserError};
+use winnow::stream::{AsBStr, AsChar, Compare, Stream, StreamIsPartial};
use winnow::token::{literal, one_of};
-use winnow::{seq, PResult, Parser};
+use winnow::{seq, Parser, Result};
use winnow_datetime::duration_part_seq;
use winnow_datetime::parser::take_digits;
use winnow_datetime::types::{Duration, DurationPart};
@@ -17,11 +17,8 @@ use winnow_datetime::types::{Duration, DurationPart};
/// let duration = winnow_iso8601::parse_duration("P1Y2M3DT4H5M6S").unwrap();
/// let duration = winnow_iso8601::parse_duration("P1W").unwrap();
/// ```
-pub fn parse_duration(mut i: &str) -> Result {
- match duration(&mut i) {
- Ok(p) => Ok(p),
- Err(e) => Err(format!("Failed to parse duration {}: {}", i, e)),
- }
+pub fn parse_duration(mut i: &str) -> Result> {
+ terminated(duration, eof).parse_next(&mut i)
}
/// Parses a duration string with the format P%dY%dM%dDT%dH%dM%dS
@@ -30,7 +27,7 @@ pub fn parse_duration(mut i: &str) -> Result {
///
/// * Fully-specified duration: `P1Y2M3DT4H5M6S`
/// * Duration in weekly intervals: `P1W`
-/// * Fully-specified duration in [`DateTime`](`crate::DateTime`) format: `P`
+/// * Fully-specified duration in [`DateTime`](`winnow_datetime::DateTime`) format: `P`
///
/// Both fully-specified formats get parsed into the YMDHMS Duration variant.
/// The weekly interval format gets parsed into the Weeks Duration variant.
@@ -47,11 +44,12 @@ pub fn parse_duration(mut i: &str) -> Result {
/// * Hour 0 - 24
/// * Minute 0 - 60
/// * Second 0 - 60
-pub fn duration<'i, Input>(i: &mut Input) -> PResult
+pub fn duration<'i, Input, Error>(input: &mut Input) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration", move |input: &mut Input| {
seq!((
@@ -86,15 +84,18 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// dur-year = 1*DIGIT "Y" [dur-month]
-pub(crate) fn duration_part_year<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_year<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_year", move |input: &mut Input| {
duration_part_seq!({
@@ -105,15 +106,18 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// dur-month = 1*DIGIT "M" [dur-day]
-pub(crate) fn duration_part_month<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_month<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_month", move |input: &mut Input| {
duration_part_seq!({
@@ -124,15 +128,18 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// dur-week = 1*DIGIT "W"
-pub(crate) fn duration_part_week<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_week<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_week", move |input: &mut Input| {
duration_part_seq!({
@@ -143,15 +150,18 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
// dur-day = 1*DIGIT "D"
-pub(crate) fn duration_part_day<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_day<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_day", move |input: &mut Input| {
duration_part_seq!({
@@ -162,16 +172,19 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// dur-hour = 1*DIGIT "H" [dur-minute]
/// dur-time = "T" (dur-hour / dur-minute / dur-second)
-pub(crate) fn duration_part_hour<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_hour<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_hour", move |input: &mut Input| {
duration_part_seq!({
@@ -182,15 +195,18 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// dur-minute = 1*DIGIT "M" [dur-second]
-pub(crate) fn duration_part_minute<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_minute<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_minute", move |input: &mut Input| {
duration_part_seq!({
@@ -201,15 +217,18 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// dur-second = 1*DIGIT "S"
-pub(crate) fn duration_part_second<'i, Input>(i: &mut Input) -> PResult
+pub(crate) fn duration_part_second<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_part_second", move |input: &mut Input| {
duration_part_seq!({
@@ -220,39 +239,47 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
/// Parses time portion of a duration
-pub fn duration_time<'i, Input>(
- i: &mut Input,
-) -> PResult<(
- Option,
- Option,
- Option,
-)>
+pub fn duration_time<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result<
+ (
+ Option,
+ Option,
+ Option,
+ ),
+ Error,
+>
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_time", move |input: &mut Input| {
preceded(opt(literal("T")), duration_base_time).parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
-pub(crate) fn duration_base_time<'i, Input>(
- i: &mut Input,
-) -> PResult<(
- Option,
- Option,
- Option,
-)>
+pub fn duration_base_time<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result<
+ (
+ Option,
+ Option,
+ Option,
+ ),
+ Error,
+>
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("duration_base_time", move |input: &mut Input| {
seq!((
@@ -264,228 +291,229 @@ where
.map(|(h, m, s)| (h, m, s))
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
#[cfg(test)]
mod parsers {
use crate::duration::*;
+ use winnow::error::InputError;
use winnow_datetime::types::DurationPart;
- use winnow_datetime::Stream;
+ use winnow_datetime::PartialInput;
#[test]
fn test_duration_year() {
assert_eq!(
- duration_part_year(&mut "2019Y".as_bstr()).unwrap(),
+ duration_part_year::<_, InputError<_>>(&mut "2019Y").unwrap(),
(DurationPart {
whole: 2019,
frac: None
})
);
assert_eq!(
- duration_part_year(&mut "0Y".as_bstr()).unwrap(),
+ duration_part_year::<_, InputError<_>>(&mut "0Y").unwrap(),
(DurationPart {
whole: 0,
frac: None
})
);
assert_eq!(
- duration_part_year(&mut "10000Y".as_bstr()).unwrap(),
+ duration_part_year::<_, InputError<_>>(&mut "10000Y").unwrap(),
(DurationPart {
whole: 10000,
frac: None
})
);
- assert!(duration_part_year(&mut Stream::new(b"abcd")).is_err());
- assert!(duration_part_year(&mut Stream::new(b"-1")).is_err());
+ assert!(duration_part_year::<_, InputError<_>>(&mut PartialInput::new(b"abcd")).is_err());
+ assert!(duration_part_year::<_, InputError<_>>(&mut PartialInput::new(b"-1")).is_err());
}
#[test]
fn test_duration_month() {
assert_eq!(
- duration_part_month(&mut "6M".as_bstr()).unwrap(),
+ duration_part_month::<_, InputError<_>>(&mut "6M").unwrap(),
(DurationPart {
whole: 6,
frac: None
})
);
assert_eq!(
- duration_part_month(&mut "0M".as_bstr()).unwrap(),
+ duration_part_month::<_, InputError<_>>(&mut "0M").unwrap(),
(DurationPart {
whole: 0,
frac: None
})
);
assert_eq!(
- duration_part_month(&mut "12M".as_bstr()).unwrap(),
+ duration_part_month::<_, InputError<_>>(&mut "12M").unwrap(),
(DurationPart {
whole: 12,
frac: None
})
);
- assert!(duration_part_month(&mut Stream::new(b"ab")).is_err());
- assert!(duration_part_month(&mut Stream::new(b"-1")).is_err());
- assert!(duration_part_month(&mut Stream::new(b"13")).is_err());
+ assert!(duration_part_month::<_, InputError<_>>(&mut PartialInput::new(b"ab")).is_err());
+ assert!(duration_part_month::<_, InputError<_>>(&mut PartialInput::new(b"-1")).is_err());
+ assert!(duration_part_month::<_, InputError<_>>(&mut PartialInput::new(b"13")).is_err());
}
#[test]
fn test_duration_week() {
assert_eq!(
- duration_part_week(&mut "26W".as_bstr()).unwrap(),
+ duration_part_week::<_, InputError<_>>(&mut "26W").unwrap(),
DurationPart {
whole: 26,
frac: None
}
);
assert_eq!(
- duration_part_week(&mut "0W".as_bstr()).unwrap(),
+ duration_part_week::<_, InputError<_>>(&mut "0W").unwrap(),
DurationPart {
whole: 0,
frac: None
}
);
assert_eq!(
- duration_part_week(&mut "52W".as_bstr()).unwrap(),
+ duration_part_week::<_, InputError<_>>(&mut "52W").unwrap(),
DurationPart {
whole: 52,
frac: None
}
);
- assert!(duration_part_week(&mut Stream::new(b"ab")).is_err());
- assert!(duration_part_week(&mut Stream::new(b"-1")).is_err());
- assert!(duration_part_week(&mut Stream::new(b"53")).is_err());
+ assert!(duration_part_week::<_, InputError<_>>(&mut PartialInput::new(b"ab")).is_err());
+ assert!(duration_part_week::<_, InputError<_>>(&mut PartialInput::new(b"-1")).is_err());
+ assert!(duration_part_week::<_, InputError<_>>(&mut PartialInput::new(b"53")).is_err());
}
#[test]
fn test_duration_day() {
assert_eq!(
- duration_part_day(&mut "16D".as_bstr()).unwrap(),
+ duration_part_day::<_, InputError<_>>(&mut "16D").unwrap(),
DurationPart {
whole: 16,
frac: None
}
);
assert_eq!(
- duration_part_day(&mut "0D".as_bstr()).unwrap(),
+ duration_part_day::<_, InputError<_>>(&mut "0D").unwrap(),
DurationPart {
whole: 0,
frac: None
}
);
assert_eq!(
- duration_part_day(&mut "31D".as_bstr()).unwrap(),
+ duration_part_day::<_, InputError<_>>(&mut "31D").unwrap(),
DurationPart {
whole: 31,
frac: None
}
);
- assert!(duration_part_day(&mut Stream::new(b"ab")).is_err());
- assert!(duration_part_day(&mut Stream::new(b"-1")).is_err());
- assert!(duration_part_day(&mut Stream::new(b"32")).is_err());
+ assert!(duration_part_day::<_, InputError<_>>(&mut PartialInput::new(b"ab")).is_err());
+ assert!(duration_part_day::<_, InputError<_>>(&mut PartialInput::new(b"-1")).is_err());
+ assert!(duration_part_day::<_, InputError<_>>(&mut PartialInput::new(b"32")).is_err());
}
#[test]
fn test_duration_hour() {
assert_eq!(
- duration_part_hour(&mut "12H".as_bstr()).unwrap(),
+ duration_part_hour::<_, InputError<_>>(&mut "12H").unwrap(),
DurationPart {
whole: 12,
frac: None
}
);
assert_eq!(
- duration_part_hour(&mut "0H".as_bstr()).unwrap(),
+ duration_part_hour::<_, InputError<_>>(&mut "0H").unwrap(),
DurationPart {
whole: 0,
frac: None
}
);
assert_eq!(
- duration_part_hour(&mut "24H".as_bstr()).unwrap(),
+ duration_part_hour::<_, InputError<_>>(&mut "24H").unwrap(),
DurationPart {
whole: 24,
frac: None
}
);
- assert!(duration_part_hour(&mut Stream::new(b"ab")).is_err());
- assert!(duration_part_hour(&mut Stream::new(b"-1")).is_err());
- assert!(duration_part_hour(&mut Stream::new(b"25")).is_err());
+ assert!(duration_part_hour::<_, InputError<_>>(&mut PartialInput::new(b"ab")).is_err());
+ assert!(duration_part_hour::<_, InputError<_>>(&mut PartialInput::new(b"-1")).is_err());
+ assert!(duration_part_hour::<_, InputError<_>>(&mut PartialInput::new(b"25")).is_err());
}
#[test]
fn test_duration_minute() {
assert_eq!(
- duration_part_minute(&mut "30M".as_bstr()).unwrap(),
+ duration_part_minute::<_, InputError<_>>(&mut "30M").unwrap(),
DurationPart {
whole: 30,
frac: None
}
);
assert_eq!(
- duration_part_minute(&mut "0M".as_bstr()).unwrap(),
+ duration_part_minute::<_, InputError<_>>(&mut "0M").unwrap(),
DurationPart {
whole: 0,
frac: None
}
);
assert_eq!(
- duration_part_minute(&mut "60M".as_bstr()).unwrap(),
+ duration_part_minute::<_, InputError<_>>(&mut "60M").unwrap(),
DurationPart {
whole: 60,
frac: None
}
);
- assert!(duration_part_minute(&mut Stream::new(b"ab")).is_err());
- assert!(duration_part_minute(&mut Stream::new(b"-1")).is_err());
- assert!(duration_part_minute(&mut Stream::new(b"61")).is_err());
+ assert!(duration_part_minute::<_, InputError<_>>(&mut PartialInput::new(b"ab")).is_err());
+ assert!(duration_part_minute::<_, InputError<_>>(&mut PartialInput::new(b"-1")).is_err());
+ assert!(duration_part_minute::<_, InputError<_>>(&mut PartialInput::new(b"61")).is_err());
}
#[test]
fn test_duration_second_and_millisecond1() {
assert_eq!(
- duration_part_second(&mut "30S".as_bstr()).unwrap(),
+ duration_part_second::<_, InputError<_>>(&mut "30S").unwrap(),
DurationPart {
whole: 30,
frac: None
}
);
assert_eq!(
- duration_part_second(&mut "0S".as_bstr()).unwrap(),
+ duration_part_second::<_, InputError<_>>(&mut "0S").unwrap(),
DurationPart {
whole: 0,
frac: None
}
);
assert_eq!(
- duration_part_second(&mut "60S".as_bstr()).unwrap(),
+ duration_part_second::<_, InputError<_>>(&mut "60S").unwrap(),
DurationPart {
whole: 60,
frac: None
}
);
assert_eq!(
- duration_part_second(&mut "1,23S".as_bstr()).unwrap(),
+ duration_part_second::<_, InputError<_>>(&mut "1,23S").unwrap(),
DurationPart {
whole: 1,
frac: Some(0.23)
}
);
assert_eq!(
- duration_part_second(&mut "2.34S".as_bstr()).unwrap(),
+ duration_part_second::<_, InputError<_>>(&mut "2.34S").unwrap(),
DurationPart {
whole: 2,
frac: Some(0.34)
}
);
- assert!(duration_part_second(&mut Stream::new(b"abS")).is_err());
- assert!(duration_part_second(&mut Stream::new(b"-1S")).is_err());
+ assert!(duration_part_second::<_, InputError<_>>(&mut PartialInput::new(b"abS")).is_err());
+ assert!(duration_part_second::<_, InputError<_>>(&mut PartialInput::new(b"-1S")).is_err());
}
#[test]
fn test_duration_time() {
assert_eq!(
- duration_time(&mut "T1H2M3S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T1H2M3S").unwrap(),
(
Some(DurationPart {
whole: 1,
@@ -502,7 +530,7 @@ mod parsers {
)
);
assert_eq!(
- duration_time(&mut "T10H12M30S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T10H12M30S").unwrap(),
(
Some(DurationPart {
whole: 10,
@@ -519,7 +547,7 @@ mod parsers {
)
);
assert_eq!(
- duration_time(&mut "T1H3S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T1H3S").unwrap(),
(
Some(DurationPart {
whole: 1,
@@ -534,7 +562,7 @@ mod parsers {
);
assert_eq!(
- duration_time(&mut "T2M".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T2M").unwrap(),
(
None,
Some(DurationPart {
@@ -545,7 +573,7 @@ mod parsers {
)
);
assert_eq!(
- duration_time(&mut "T1H2M3,4S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T1H2M3,4S").unwrap(),
(
Some(DurationPart {
whole: 1,
@@ -562,7 +590,7 @@ mod parsers {
)
);
assert_eq!(
- duration_time(&mut "T1H23.4S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T1H23.4S").unwrap(),
(
Some(DurationPart {
whole: 1,
@@ -576,7 +604,7 @@ mod parsers {
)
);
assert_eq!(
- duration_time(&mut "T0,123S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T0,123S").unwrap(),
(
None,
None,
@@ -587,7 +615,7 @@ mod parsers {
)
);
assert_eq!(
- duration_time(&mut "T0123S".as_bstr()).unwrap(),
+ duration_time::<_, InputError<_>>(&mut "T0123S").unwrap(),
(
None,
None,
@@ -601,24 +629,26 @@ mod parsers {
#[test]
fn test_duration_ymdhms_error() {
- assert!(duration(&mut Stream::new(b"")).is_err());
- assert!(duration(&mut Stream::new(b"P")).is_err()); // empty duration is not 0 seconds
- assert!(duration(&mut Stream::new(b"1Y2M3DT4H5M6S")).is_err()); // missing P at start
- assert!(duration(&mut Stream::new(b"T4H5M6S")).is_err()); // missing P,
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"")).is_err());
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"P")).is_err()); // empty duration is not 0 seconds
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"1Y2M3DT4H5M6S")).is_err()); // missing P at start
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"T4H5M6S")).is_err());
+ // missing P,
}
#[test]
fn test_duration_weeks_error() {
- assert!(duration(&mut Stream::new(b"")).is_err());
- assert!(duration(&mut Stream::new(b"P")).is_err()); // empty duration is not 0 seconds
- assert!(duration(&mut Stream::new(b"P1")).is_err()); // missing W after number
- assert!(duration(&mut Stream::new(b"PW")).is_err()); // missing number
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"")).is_err());
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"P")).is_err()); // empty duration is not 0 seconds
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"P1")).is_err()); // missing W after number
+ assert!(duration::<_, InputError<_>>(&mut PartialInput::new(b"PW")).is_err());
+ // missing number
}
#[test]
fn test_duration_second() {
assert_eq!(
- duration(&mut "PT30S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT30S").unwrap(),
Duration {
years: 0,
months: 0,
@@ -631,7 +661,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "PT30.123S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT30.123S").unwrap(),
Duration {
years: 0,
months: 0,
@@ -644,7 +674,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16DT23H26M59.123S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16DT23H26M59.123S").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -661,7 +691,7 @@ mod parsers {
#[test]
fn duration_roundtrip() {
assert_eq!(
- duration(&mut "P0W".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P0W").unwrap(),
Duration {
years: 0,
months: 0,
@@ -674,7 +704,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16DT23H26M59S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16DT23H26M59S").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -687,7 +717,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16DT23H26M".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16DT23H26M").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -700,7 +730,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16DT23H".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16DT23H").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -713,7 +743,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16D".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16D").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -726,7 +756,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16DT1S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16DT1S").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -739,7 +769,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M16DT0.471S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M16DT0.471S").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -752,7 +782,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P2021Y11M".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P2021Y11M").unwrap(),
Duration {
years: 2021,
months: 11,
@@ -765,7 +795,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P11M".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P11M").unwrap(),
Duration {
years: 0,
months: 11,
@@ -778,7 +808,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P16D".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P16D").unwrap(),
Duration {
years: 0,
months: 0,
@@ -791,7 +821,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P0D".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P0D").unwrap(),
Duration {
years: 0,
months: 0,
@@ -808,7 +838,7 @@ mod parsers {
#[test]
fn duration_multi_digit_hour() {
assert_eq!(
- duration(&mut "PT12H".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT12H").unwrap(),
Duration {
years: 0,
months: 0,
@@ -821,7 +851,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "PT8760H".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT8760H").unwrap(),
Duration {
years: 0,
months: 0,
@@ -838,7 +868,7 @@ mod parsers {
#[test]
fn duration_multi_digit_minute() {
assert_eq!(
- duration(&mut "PT15M".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT15M").unwrap(),
Duration {
years: 0,
months: 0,
@@ -851,7 +881,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "PT600M".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT600M").unwrap(),
Duration {
years: 0,
months: 0,
@@ -868,7 +898,7 @@ mod parsers {
#[test]
fn duration_multi_digit_second() {
assert_eq!(
- duration(&mut "PT16S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT16S").unwrap(),
Duration {
years: 0,
months: 0,
@@ -881,7 +911,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "PT900S".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "PT900S").unwrap(),
Duration {
years: 0,
months: 0,
@@ -898,7 +928,7 @@ mod parsers {
#[test]
fn duration_multi_digit_day() {
assert_eq!(
- duration(&mut "P365D".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P365D").unwrap(),
Duration {
years: 0,
months: 0,
@@ -911,7 +941,7 @@ mod parsers {
}
);
assert_eq!(
- duration(&mut "P36500D".as_bstr()).unwrap(),
+ duration::<_, InputError<_>>(&mut "P36500D").unwrap(),
Duration {
years: 0,
months: 0,
diff --git a/crates/winnow-iso8601/src/fractional_duration.rs b/crates/winnow-iso8601/src/fractional_duration.rs
index 2ed5dcc..e5acc20 100644
--- a/crates/winnow-iso8601/src/fractional_duration.rs
+++ b/crates/winnow-iso8601/src/fractional_duration.rs
@@ -1,38 +1,30 @@
use crate::duration::{
- duration, duration_base_time, duration_part_day, duration_part_month, duration_part_week,
+ duration_base_time, duration_part_day, duration_part_month, duration_part_week,
duration_part_year,
};
-use alloc::string::String;
-use winnow::combinator::{opt, preceded, trace};
-use winnow::stream::{AsBStr, AsChar, Compare, Stream as InputStream, StreamIsPartial};
+use winnow::combinator::{eof, opt, preceded, terminated, trace};
+use winnow::error::{InputError, ParserError};
+use winnow::stream::{AsBStr, AsChar, Compare, Stream, StreamIsPartial};
use winnow::token::literal;
-use winnow::{seq, PResult, Parser};
-use winnow_datetime::types::Duration;
+use winnow::{seq, Parser, Result};
use winnow_datetime::FractionalDuration;
/// Parses a duration with the same formating rules but allows for decimal places.
-pub fn parse_duration(mut i: &str) -> Result {
- match duration(&mut i) {
- Ok(p) => Ok(p),
- Err(e) => Err(format!("Failed to parse duration {}: {}", i, e)),
- }
-}
-
/// let duration = winnow_iso8601::parse_fractional_duration("P1,5Y2M3DT4,5H5M6S").unwrap();
/// let duration = winnow_iso8601::parse_fractional_duration("P1,5W").unwrap();
-pub fn parse_fractional_duration(mut i: &str) -> Result {
- match fractional_duration(&mut i) {
- Ok(p) => Ok(p),
- Err(e) => Err(format!("Failed to parse duration {}: {}", i, e)),
- }
+pub fn parse_fractional_duration(mut i: &str) -> Result> {
+ terminated(fractional_duration, eof).parse_next(&mut i)
}
/// Parses a duration string with the format P%dY%dM%dDT%dH%dM%dS
-pub fn fractional_duration<'i, Input>(i: &mut Input) -> PResult
+pub fn fractional_duration<'i, Input, Error>(
+ input: &mut Input,
+) -> std::result::Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("fractional_duration", move |input: &mut Input| {
seq!((
@@ -66,5 +58,5 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
diff --git a/crates/winnow-iso8601/src/interval.rs b/crates/winnow-iso8601/src/interval.rs
index 5ea7cdc..55fc60d 100644
--- a/crates/winnow-iso8601/src/interval.rs
+++ b/crates/winnow-iso8601/src/interval.rs
@@ -1,13 +1,12 @@
use crate::duration::duration;
use crate::partial_datetime::{partial_datetime, partial_end_datetime};
-use alloc::string::String;
-use core::str;
-use winnow::combinator::alt;
use winnow::combinator::opt;
use winnow::combinator::trace;
-use winnow::stream::{AsBStr, AsChar, Compare, Stream as InputStream, StreamIsPartial};
+use winnow::combinator::{alt, eof, terminated};
+use winnow::error::{InputError, ParserError};
+use winnow::stream::{AsBStr, AsChar, Compare, Stream, StreamIsPartial};
use winnow::token::literal;
-use winnow::{seq, PResult, Parser};
+use winnow::{seq, Parser, Result};
use winnow_datetime::parser::take_digits;
use winnow_datetime::types::{Interval, IntervalRange};
@@ -16,19 +15,17 @@ use winnow_datetime::types::{Interval, IntervalRange};
/// A string that optionally starts with `R` and contains a combination of partial date-times in the
/// following permissible formats:
///
-pub fn parse_interval(mut i: &str) -> Result {
- match interval(&mut i) {
- Ok(p) => Ok(p),
- Err(e) => Err(format!("Failed to parse interval {}: {}", i, e)),
- }
+pub fn parse_interval(mut i: &str) -> Result> {
+ terminated(interval, eof).parse_next(&mut i)
}
/// Parses a interval string containing combinations of partial date-times and duration.
-pub fn interval<'i, Input>(i: &mut Input) -> PResult
+pub fn interval<'i, Input, Error>(input: &mut Input) -> Result
where
- Input: StreamIsPartial + InputStream + Compare<&'i str>,
- ::Slice: AsBStr,
- ::Token: AsChar + Clone,
+ Input: StreamIsPartial + Stream + Compare<&'i str>,
+ ::Slice: AsBStr,
+ ::Token: AsChar + Clone,
+ Error: ParserError,
{
trace("interval", move |input: &mut Input| {
seq!(Interval {
@@ -42,40 +39,43 @@ where
})
.parse_next(input)
})
- .parse_next(i)
+ .parse_next(input)
}
-fn interval_repetitions<'i, Input>(i: &mut Input) -> PResult