aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-John Tedro <udoprog@tedro.se>2018-05-07 05:36:09 +0200
committerJohn-John Tedro <udoprog@tedro.se>2018-05-07 05:36:41 +0200
commit2b40d542a0ea645c5e3c132aabc0082dffa2f554 (patch)
treef9b9c4a633e03cfaf942ef5d880e37428a1f7ba2
parent579cf491e6cca04b5e4cfe63f3132eed1f2a4e93 (diff)
downloadmilf-rs-2b40d542a0ea645c5e3c132aabc0082dffa2f554.tar.gz
milf-rs-2b40d542a0ea645c5e3c132aabc0082dffa2f554.zip
Fix incorrectly reported spans for Datetime
-rw-r--r--src/de.rs36
-rw-r--r--src/lib.rs1
-rw-r--r--test-suite/tests/spanned.rs23
3 files changed, 47 insertions, 13 deletions
diff --git a/src/de.rs b/src/de.rs
index 5521e00..1d43cc9 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -853,16 +853,16 @@ impl<'a> Deserializer<'a> {
{
if s.contains('T') || (s.len() > 1 && s[1..].contains('-')) &&
!s.contains("e-") {
- self.datetime(s, false).map(|d| Value {
+ self.datetime(span, s, false).map(|(Span { start, end }, d)| Value {
e: E::Datetime(d),
- start: span.start,
- end: span.end
+ start: start,
+ end: end
})
} else if self.eat(Token::Colon)? {
- self.datetime(s, true).map(|d| Value {
+ self.datetime(span, s, true).map(|(Span { start, end }, d)| Value {
e: E::Datetime(d),
- start: span.start,
- end: span.end
+ start: start,
+ end: end
})
} else {
self.number(span, s)
@@ -1006,9 +1006,10 @@ impl<'a> Deserializer<'a> {
})
}
- fn datetime(&mut self, date: &'a str, colon_eaten: bool)
- -> Result<&'a str, Error> {
+ fn datetime(&mut self, mut span: Span, date: &'a str, colon_eaten: bool)
+ -> Result<(Span, &'a str), Error> {
let start = self.tokens.substr_offset(date);
+
if colon_eaten || self.eat(Token::Colon)? {
// minutes
match self.next()? {
@@ -1018,13 +1019,17 @@ impl<'a> Deserializer<'a> {
// Seconds
self.expect(Token::Colon)?;
match self.next()? {
- Some((_, Token::Keylike(_))) => {}
+ Some((Span { end, .. }, Token::Keylike(_))) => {
+ span.end = end;
+ },
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
}
// Fractional seconds
if self.eat(Token::Period)? {
match self.next()? {
- Some((_, Token::Keylike(_))) => {}
+ Some((Span { end, .. }, Token::Keylike(_))) => {
+ span.end = end;
+ },
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
}
}
@@ -1032,19 +1037,24 @@ impl<'a> Deserializer<'a> {
// offset
if self.eat(Token::Plus)? {
match self.next()? {
- Some((_, Token::Keylike(_))) => {}
+ Some((Span { end, .. }, Token::Keylike(_))) => {
+ span.end = end;
+ },
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
}
}
if self.eat(Token::Colon)? {
match self.next()? {
- Some((_, Token::Keylike(_))) => {}
+ Some((Span { end, .. }, Token::Keylike(_))) => {
+ span.end = end;
+ },
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
}
}
}
+
let end = self.tokens.current();
- Ok(&self.tokens.input()[start..end])
+ Ok((span, &self.tokens.input()[start..end]))
}
// TODO(#140): shouldn't buffer up this entire table in memory, it'd be
diff --git a/src/lib.rs b/src/lib.rs
index b90612c..6fbf5d5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -171,4 +171,5 @@ mod tokens;
pub mod macros;
pub mod spanned;
+#[doc(no_inline)]
pub use spanned::Spanned;
diff --git a/test-suite/tests/spanned.rs b/test-suite/tests/spanned.rs
index c5dc28e..4339a0c 100644
--- a/test-suite/tests/spanned.rs
+++ b/test-suite/tests/spanned.rs
@@ -4,8 +4,26 @@ extern crate toml;
extern crate serde_derive;
use toml::Spanned;
+use toml::value::Datetime;
use std::collections::HashMap;
+/// A set of good datetimes.
+pub fn good_datetimes() -> Vec<&'static str> {
+ let mut v = Vec::new();
+ v.push("1997-09-09T09:09:09Z");
+ v.push("1997-09-09T09:09:09+09:09");
+ v.push("1997-09-09T09:09:09-09:09");
+ v.push("1997-09-09T09:09:09");
+ v.push("1997-09-09");
+ v.push("09:09:09");
+ v.push("1997-09-09T09:09:09.09Z");
+ v.push("1997-09-09T09:09:09.09+09:09");
+ v.push("1997-09-09T09:09:09.09-09:09");
+ v.push("1997-09-09T09:09:09.09");
+ v.push("09:09:09.09");
+ v
+}
+
#[test]
fn test_spanned_field() {
#[derive(Deserialize)]
@@ -40,4 +58,9 @@ fn test_spanned_field() {
"foo = \"1997-09-09T09:09:09Z\"",
"\"1997-09-09T09:09:09Z\""
);
+
+ for expected in good_datetimes() {
+ let s = format!("foo = {}", expected);
+ good::<Datetime>(&s, expected);
+ }
}