Skip to content
Closed
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repository = "https://github.com/pydantic/speedate/"
[dependencies]
strum = { version = "0.25", features = ["derive"] }
strum_macros = "0.25"
lexical-core = { version = "0.8.5", features = ["format"] }

[dev-dependencies]
chrono = "0.4.19"
Expand Down
8 changes: 4 additions & 4 deletions src/date.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;

use crate::numbers::int_parse_bytes;
use crate::numbers::parse_int_with_json_semantics;
use crate::{get_digit_unchecked, DateTime, ParseError};

/// A Date
Expand Down Expand Up @@ -159,9 +159,9 @@ impl Date {
pub fn parse_bytes(bytes: &[u8]) -> Result<Self, ParseError> {
match Self::parse_bytes_rfc3339(bytes) {
Ok(d) => Ok(d),
Err(e) => match int_parse_bytes(bytes) {
Some(int) => Self::from_timestamp(int, true),
None => Err(e),
Err(e) => match parse_int_with_json_semantics(bytes) {
Some(int_or_float) => Self::from_timestamp(int_or_float, true),
_ => Err(e),
},
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/numbers.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
use lexical_core::{format as lexical_format, parse_with_options, ParseIntegerOptions};

// Parse bytes as an int with JSON semantics.
pub fn parse_int_with_json_semantics(bytes: &[u8]) -> Option<i64> {
const JSON: u128 = lexical_format::JSON;
let int_options = ParseIntegerOptions::new();
let int_result: Result<i64, lexical_core::Error> = parse_with_options::<i64, JSON>(bytes, &int_options);

match int_result {
Ok(parsed_int) => Some(parsed_int),
Err(_) => None,
}
}
Comment on lines +3 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By introducing a new function here it looks like int_parse_bytes and int_parse_str will continue to accept + and - as valid integers. Might it be better to instead fix those functions to reject those inputs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed #51 as an alternative.


/// Parse a string as an int.
///
/// This is around 2x faster than using `str::parse::<i64>()`
Expand Down
11 changes: 11 additions & 0 deletions tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1348,3 +1348,14 @@ fn test_time_config_builder() {
);
assert_eq!(TimeConfigBuilder::new().build(), TimeConfig::builder().build());
}

#[test]
fn date_dash_err() {
let error = match Date::parse_str("-") {
Ok(_) => panic!("unexpectedly valid"),
Err(e) => e,
};
assert_eq!(error, ParseError::TooShort);
assert_eq!(error.to_string(), "too_short");
assert_eq!(error.get_documentation(), Some("input is too short"));
}