fix problem parsing entities

issue with how bytes are not a collection -> bytes not correctly viewed as atoms
This commit is contained in:
Mark Watts 2021-08-23 17:23:09 -04:00
parent 179c123061
commit d3821432bc
3 changed files with 17 additions and 4 deletions

View file

@ -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)

View file

@ -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)
}
}
};

View file

@ -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.