[edn] Round-trip instants. (#686) (#687) r=rnewman

First, the parser had a small grouping bug where-by it wouldn't parse
Z as timezone correctly.  Second, we weren't printing instants in the format
that we parse.
This commit is contained in:
Nick Alexander 2018-05-11 02:11:04 -07:00 committed by Richard Newman
parent 37a6f7be28
commit c8f74fa41b
4 changed files with 31 additions and 4 deletions

View file

@ -101,7 +101,7 @@ inst_string -> DateTime<Utc> =
"T"
[0-2][0-9] ":" [0-5][0-9] ":" [0-6][0-9]
("." [0-9]+)?
"Z" / (("+" / "-") [0-2][0-9] ":" [0-5][0-9])
("Z" / (("+" / "-") [0-2][0-9] ":" [0-5][0-9]))
)
"\"" {?
DateTime::parse_from_rfc3339(d)

View file

@ -8,6 +8,10 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use chrono::{
SecondsFormat,
};
use itertools::Itertools;
use pretty;
@ -70,6 +74,7 @@ impl Value {
Value::Keyword(ref v) => pp.text(":").append(v.0.as_ref()),
Value::Text(ref v) => pp.text("\"").append(v.as_ref()).append("\""),
Value::Uuid(ref u) => pp.text("#uuid \"").append(u.hyphenated().to_string()).append("\""),
Value::Instant(ref v) => pp.text("#inst \"").append(v.to_rfc3339_opts(SecondsFormat::AutoSi, true)).append("\""),
_ => pp.text(self.to_string())
}
}

View file

@ -17,6 +17,7 @@ use std::f64;
use chrono::{
DateTime,
SecondsFormat,
TimeZone, // For Utc::timestamp. The compiler incorrectly complains that this is unused.
Utc,
};
@ -461,7 +462,7 @@ macro_rules! def_common_value_display {
$t::Nil => write!($f, "nil"),
$t::Boolean(v) => write!($f, "{}", v),
$t::Integer(v) => write!($f, "{}", v),
$t::Instant(v) => write!($f, "{}", v),
$t::Instant(v) => write!($f, "#inst \"{}\"", v.to_rfc3339_opts(SecondsFormat::AutoSi, true)),
$t::BigInteger(ref v) => write!($f, "{}N", v),
// TODO: make sure float syntax is correct.
$t::Float(ref v) => {

View file

@ -264,10 +264,31 @@ fn test_uuid() {
let expected = uuid::Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")
.expect("valid UUID");
let actual = parse::uuid("#uuid \"550e8400-e29b-41d4-a716-446655440000\"")
let s = "#uuid \"550e8400-e29b-41d4-a716-446655440000\"";
let actual = parse::uuid(s)
.expect("parse success")
.into();
assert_eq!(self::Value::Uuid(expected), actual);
let value = self::Value::Uuid(expected);
assert_eq!(value, actual);
assert_eq!(format!("{}", value), s);
assert_eq!(value.to_pretty(100).unwrap(), s);
}
#[test]
fn test_inst() {
assert!(parse::value("#inst\"2016-01-01T11:00:00.000Z\"").is_err()); // No whitespace.
assert!(parse::value("#inst \"2016-01-01T11:00:00.000\"").is_err()); // No timezone.
assert!(parse::value("#inst \"2016-01-01T11:00:00.000z\"").is_err()); // Lowercase timezone.
let expected = Utc.timestamp(1493410985, 187000000);
let s = "#inst \"2017-04-28T20:23:05.187Z\"";
let actual = parse::value(s)
.expect("parse success")
.into();
let value = self::Value::Instant(expected);
assert_eq!(value, actual);
assert_eq!(format!("{}", value), s);
assert_eq!(value.to_pretty(100).unwrap(), s);
}
#[test]