Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/items/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ where
/// following two forms:
///
/// - 0
/// - [+-][1-9][0-9]*
/// - [+-]?[1-9][0-9]*
///
/// Inputs like [+-]0[0-9]* (e.g., `+012`) are therefore rejected. We provide a
/// Inputs like [+-]?0[0-9]* (e.g., `+012`) are therefore rejected. We provide a
/// custom implementation to support such zero-prefixed integers.
fn dec_int<'a, E>(input: &mut &'a str) -> winnow::Result<i32, E>
where
Expand Down Expand Up @@ -175,6 +175,23 @@ where
.parse_next(input)
}

/// Parse a float number.
///
/// Rationale for not using `winnow::ascii::float`: the `float` parser provided
/// by winnow accepts E-notation numbers (e.g., `1.23e4`), whereas GNU date
/// rejects such numbers. To remain compatible with GNU date, we provide a
/// custom implementation that only accepts inputs like [+-]?[0-9]+(\.[0-9]+)?.
fn float<'a, E>(input: &mut &'a str) -> winnow::Result<f64, E>
where
E: ParserError<&'a str>,
{
(opt(one_of(['+', '-'])), digit1, opt(preceded('.', digit1)))
.void()
.take()
.verify_map(|s: &str| s.parse().ok())
.parse_next(input)
}

// Parse an item
pub fn parse_one(input: &mut &str) -> ModalResult<Item> {
trace(
Expand Down
4 changes: 2 additions & 2 deletions src/items/relative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
//! > ‘this thursday’.

use winnow::{
ascii::{alpha1, float},
ascii::alpha1,
combinator::{alt, opt},
ModalResult, Parser,
};

use super::{ordinal::ordinal, s};
use super::{float, ordinal::ordinal, s};

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Relative {
Expand Down
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,13 @@ mod tests {

#[test]
fn invalid_formats() {
let invalid_dts = vec!["NotADate", "202104", "202104-12T22:37:47"];
let invalid_dts = vec![
"NotADate",
"202104",
"202104-12T22:37:47",
"a774e26sec", // 774e26 is not a valid seconds value (we don't accept E-notation)
"12.", // Invalid floating point number
];
for dt in invalid_dts {
assert_eq!(parse_datetime(dt), Err(ParseDateTimeError::InvalidInput));
}
Expand Down
Loading