From d3821432bcf2dd0862bca3cb6da2868e5371f4ca Mon Sep 17 00:00:00 2001 From: Mark Watts Date: Mon, 23 Aug 2021 17:23:09 -0400 Subject: [PATCH] fix problem parsing entities issue with how bytes are not a collection -> bytes not correctly viewed as atoms --- edn/src/lib.rs | 5 +++-- edn/src/types.rs | 4 ++-- edn/tests/tests.rs | 12 ++++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/edn/src/lib.rs b/edn/src/lib.rs index 1d1cfec2..dfa846ac 100644 --- a/edn/src/lib.rs +++ b/edn/src/lib.rs @@ -177,12 +177,13 @@ peg::parser!(pub grammar parse() for str { { SpannedValue::Uuid(u) } rule byte_buffer() -> Bytes = - u:$( ['a'..='f' | 'A'..='F' | '0'..='9']* ) { + u:$( hex()+ ) { let b = decode(u).expect("this is a valid hex byte string"); Bytes::copy_from_slice(&b) } pub rule bytes() -> SpannedValue = "#bytes" whitespace()+ u:byte_buffer() { SpannedValue::Bytes(u) } + rule namespace_divider() = "." rule namespace_separator() = "/" @@ -230,7 +231,7 @@ peg::parser!(pub grammar parse() for str { // Note: It's important that float comes before integer or the parser assumes that floats are integers and fails to parse. pub rule value() -> ValueAndSpan = - __ start:position!() v:(nil() / nan() / infinity() / boolean() / number() / inst() / uuid() / text() / keyword() / symbol() / list() / vector() / map() / set() / bytes() ) end:position!() __ { + __ start:position!() v:(nil() / nan() / infinity() / boolean() / number() / inst() / uuid() / bytes() / text() / keyword() / symbol() / list() / vector() / map() / set() ) end:position!() __ { ValueAndSpan { inner: v, span: Span::new(start, end) diff --git a/edn/src/types.rs b/edn/src/types.rs index 37d4158a..818b0453 100644 --- a/edn/src/types.rs +++ b/edn/src/types.rs @@ -496,7 +496,7 @@ macro_rules! def_common_value_methods { $t::List(_) => true, $t::Set(_) => true, $t::Map(_) => true, - $t::Bytes(_) => true, + $t::Bytes(_) => false, } } @@ -603,7 +603,7 @@ macro_rules! def_common_value_display { } $t::Bytes(ref v) => { let s = encode(v); - write!($f, "#bytes \"{}\"", s) + write!($f, "#bytes {}", s) } } }; diff --git a/edn/tests/tests.rs b/edn/tests/tests.rs index 077f3265..2baa6923 100644 --- a/edn/tests/tests.rs +++ b/edn/tests/tests.rs @@ -336,8 +336,20 @@ fn test_bytes() { 1, 2, 3, 5, 4, 3, 2, 42 ))) ); + let data = r#"[ { :test/instant #inst "2018-01-01T11:00:00Z" :test/bytes #bytes 010203050403022a } ]"#; + let result = parse::value(data).unwrap().without_spans().to_string(); + assert_eq!(data, result); } + +#[test] +fn test_entities() { + let d2 = r#"[ { :test/boolean true :test/long 33 :test/double 1.4 :test/string "foo" :test/keyword :foo/bar :test/uuid #uuid "12341234-1234-1234-1234-123412341234" :test/instant #inst "2018-01-01T11:00:00Z" :test/ref 1 :test/bytes #bytes 010203050403022a } ]"#; + let r2 = parse::entities(d2); + assert!(r2.is_ok()); +} + + #[test] fn test_inst() { assert!(parse::value("#inst\"2016-01-01T11:00:00.000Z\"").is_err()); // No whitespace.