Fix incorrectly reported spans for Datetime
This commit is contained in:
parent
8a9ae07de5
commit
407845d620
36
src/de.rs
36
src/de.rs
|
@ -853,16 +853,16 @@ impl<'a> Deserializer<'a> {
|
||||||
{
|
{
|
||||||
if s.contains('T') || (s.len() > 1 && s[1..].contains('-')) &&
|
if s.contains('T') || (s.len() > 1 && s[1..].contains('-')) &&
|
||||||
!s.contains("e-") {
|
!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),
|
e: E::Datetime(d),
|
||||||
start: span.start,
|
start: start,
|
||||||
end: span.end
|
end: end
|
||||||
})
|
})
|
||||||
} else if self.eat(Token::Colon)? {
|
} 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),
|
e: E::Datetime(d),
|
||||||
start: span.start,
|
start: start,
|
||||||
end: span.end
|
end: end
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.number(span, s)
|
self.number(span, s)
|
||||||
|
@ -1006,9 +1006,10 @@ impl<'a> Deserializer<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn datetime(&mut self, date: &'a str, colon_eaten: bool)
|
fn datetime(&mut self, mut span: Span, date: &'a str, colon_eaten: bool)
|
||||||
-> Result<&'a str, Error> {
|
-> Result<(Span, &'a str), Error> {
|
||||||
let start = self.tokens.substr_offset(date);
|
let start = self.tokens.substr_offset(date);
|
||||||
|
|
||||||
if colon_eaten || self.eat(Token::Colon)? {
|
if colon_eaten || self.eat(Token::Colon)? {
|
||||||
// minutes
|
// minutes
|
||||||
match self.next()? {
|
match self.next()? {
|
||||||
|
@ -1018,13 +1019,17 @@ impl<'a> Deserializer<'a> {
|
||||||
// Seconds
|
// Seconds
|
||||||
self.expect(Token::Colon)?;
|
self.expect(Token::Colon)?;
|
||||||
match self.next()? {
|
match self.next()? {
|
||||||
Some((_, Token::Keylike(_))) => {}
|
Some((Span { end, .. }, Token::Keylike(_))) => {
|
||||||
|
span.end = end;
|
||||||
|
},
|
||||||
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
||||||
}
|
}
|
||||||
// Fractional seconds
|
// Fractional seconds
|
||||||
if self.eat(Token::Period)? {
|
if self.eat(Token::Period)? {
|
||||||
match self.next()? {
|
match self.next()? {
|
||||||
Some((_, Token::Keylike(_))) => {}
|
Some((Span { end, .. }, Token::Keylike(_))) => {
|
||||||
|
span.end = end;
|
||||||
|
},
|
||||||
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,19 +1037,24 @@ impl<'a> Deserializer<'a> {
|
||||||
// offset
|
// offset
|
||||||
if self.eat(Token::Plus)? {
|
if self.eat(Token::Plus)? {
|
||||||
match self.next()? {
|
match self.next()? {
|
||||||
Some((_, Token::Keylike(_))) => {}
|
Some((Span { end, .. }, Token::Keylike(_))) => {
|
||||||
|
span.end = end;
|
||||||
|
},
|
||||||
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.eat(Token::Colon)? {
|
if self.eat(Token::Colon)? {
|
||||||
match self.next()? {
|
match self.next()? {
|
||||||
Some((_, Token::Keylike(_))) => {}
|
Some((Span { end, .. }, Token::Keylike(_))) => {
|
||||||
|
span.end = end;
|
||||||
|
},
|
||||||
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
_ => return Err(self.error(start, ErrorKind::DateInvalid)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let end = self.tokens.current();
|
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
|
// TODO(#140): shouldn't buffer up this entire table in memory, it'd be
|
||||||
|
|
|
@ -171,4 +171,5 @@ mod tokens;
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
|
|
||||||
pub mod spanned;
|
pub mod spanned;
|
||||||
|
#[doc(no_inline)]
|
||||||
pub use spanned::Spanned;
|
pub use spanned::Spanned;
|
||||||
|
|
|
@ -4,8 +4,26 @@ extern crate toml;
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use toml::Spanned;
|
use toml::Spanned;
|
||||||
|
use toml::value::Datetime;
|
||||||
use std::collections::HashMap;
|
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]
|
#[test]
|
||||||
fn test_spanned_field() {
|
fn test_spanned_field() {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -40,4 +58,9 @@ fn test_spanned_field() {
|
||||||
"foo = \"1997-09-09T09:09:09Z\"",
|
"foo = \"1997-09-09T09:09:09Z\"",
|
||||||
"\"1997-09-09T09:09:09Z\""
|
"\"1997-09-09T09:09:09Z\""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for expected in good_datetimes() {
|
||||||
|
let s = format!("foo = {}", expected);
|
||||||
|
good::<Datetime>(&s, expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue