forked from syndicate-lang/preserves
Codec; implement Rust tests; samples.txt in quasi-canonical serialized order
This commit is contained in:
parent
199ce1fdba
commit
ef3b88147e
|
@ -207,12 +207,11 @@ mod decoder_tests {
|
|||
#[cfg(test)]
|
||||
mod samples_tests {
|
||||
use crate::symbol::Symbol;
|
||||
use crate::value::Decoder;
|
||||
use crate::value::{Codec, Decoder, codec};
|
||||
use crate::value::{Value, AValue};
|
||||
use crate::value::DecodePlaceholderMap;
|
||||
use crate::value::to_value;
|
||||
use crate::value::from_value;
|
||||
use crate::value::invert_map;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
|
@ -235,20 +234,58 @@ mod samples_tests {
|
|||
DecodeShort(#[serde(with = "serde_bytes")] Vec<u8>),
|
||||
}
|
||||
|
||||
#[test] fn run() {
|
||||
#[test] fn run() -> codec::Result<()> {
|
||||
let mut d = Decoder::new(std::fs::File::open("../../tests/samples.bin").unwrap(), None);
|
||||
let tests: TestCases = from_value(&d.next().unwrap()).unwrap();
|
||||
let decode_placeholders = tests.decode_placeholders.0;
|
||||
let encode_placeholders = invert_map(&decode_placeholders);
|
||||
|
||||
// println!("{:#?}", tests);
|
||||
println!("{:#?}", decode_placeholders);
|
||||
println!("{:#?}", encode_placeholders);
|
||||
|
||||
let codec = Codec::new(tests.decode_placeholders.0);
|
||||
for (Symbol(ref name), ref case) in tests.tests {
|
||||
println!("{:?} ==> {:?}", name, case);
|
||||
match case {
|
||||
TestCase::Test(ref bin, ref val) => {
|
||||
assert_eq!(&codec.decode(&codec.encode_bytes(val)?[..])?, val);
|
||||
assert_eq!(&codec.decode(&bin[..])?, val);
|
||||
assert_eq!(&codec.encode_bytes(val)?, bin);
|
||||
}
|
||||
TestCase::NondeterministicTest(ref bin, ref val) => {
|
||||
// The test cases in samples.txt are carefully
|
||||
// written so that while strictly
|
||||
// "nondeterministic", the order of keys in
|
||||
// dictionaries follows Preserves order.
|
||||
assert_eq!(&codec.decode(&codec.encode_bytes(val)?[..])?, val);
|
||||
assert_eq!(&codec.decode(&bin[..])?, val);
|
||||
assert_eq!(&codec.encode_bytes(val)?, bin);
|
||||
}
|
||||
TestCase::StreamingTest(ref bin, ref val) => {
|
||||
assert_eq!(&codec.decode(&codec.encode_bytes(val)?[..])?, val);
|
||||
assert_eq!(&codec.decode(&bin[..])?, val);
|
||||
}
|
||||
TestCase::ParseError(_) => (),
|
||||
TestCase::ParseShort(_) => (),
|
||||
TestCase::DecodeError(ref bin) => {
|
||||
match codec.decode(&bin[..]) {
|
||||
Ok(_) => panic!("Unexpected success"),
|
||||
Err(codec::Error::Syntax(_)) => (),
|
||||
Err(e) => panic!("Unexpected error {:?}", e),
|
||||
}
|
||||
}
|
||||
TestCase::DecodeShort(ref bin) => {
|
||||
match codec.decode(&bin[..]) {
|
||||
Ok(_) => panic!("Unexpected success"),
|
||||
Err(codec::Error::Eof) => (),
|
||||
Err(e) => panic!("Unexpected error {:?}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test] fn simple_to_value() {
|
||||
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
struct SimpleValue<'a>(String,
|
||||
#[serde(with = "crate::symbol")] String,
|
||||
Symbol,
|
||||
&'a str,
|
||||
#[serde(with = "serde_bytes")] &'a [u8],
|
||||
|
@ -256,7 +293,8 @@ mod samples_tests {
|
|||
i16,
|
||||
AValue);
|
||||
let v = SimpleValue("hello".to_string(),
|
||||
Symbol("sym".to_string()),
|
||||
"sym1".to_string(),
|
||||
Symbol("sym2".to_string()),
|
||||
"world",
|
||||
&b"slice"[..],
|
||||
b"vec".to_vec(),
|
||||
|
|
|
@ -16,3 +16,15 @@ impl<'de> serde::Deserialize<'de> for Symbol {
|
|||
Ok(Symbol(s.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serialize<S>(s: &str, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
use serde::Serialize;
|
||||
Symbol(s.to_string()).serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) ->
|
||||
Result<String, D::Error> where D: serde::Deserializer<'de>
|
||||
{
|
||||
use serde::Deserialize;
|
||||
Symbol::deserialize(deserializer).map(|v| v.0)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
use crate::value::{decoder, encoder, invert_map, AValue};
|
||||
use decoder::{Decoder, DecodePlaceholderMap};
|
||||
use encoder::{Encoder, EncodePlaceholderMap};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
pub type Error = decoder::Error;
|
||||
pub type Result<T> = decoder::Result<T>;
|
||||
|
||||
pub struct Codec {
|
||||
pub decode_placeholders: Option<DecodePlaceholderMap>,
|
||||
pub encode_placeholders: Option<EncodePlaceholderMap>,
|
||||
}
|
||||
|
||||
impl Codec {
|
||||
pub fn new(decode_placeholders: DecodePlaceholderMap) -> Self {
|
||||
let encode_placeholders = Some(invert_map(&decode_placeholders));
|
||||
Codec { decode_placeholders: Some(decode_placeholders), encode_placeholders }
|
||||
}
|
||||
|
||||
pub fn without_placeholders() -> Self {
|
||||
Codec { decode_placeholders: None, encode_placeholders: None }
|
||||
}
|
||||
|
||||
pub fn decoder<'a, R: Read>(&'a self, read: R) -> Decoder<'a, R> {
|
||||
Decoder::new(read, self.decode_placeholders.as_ref())
|
||||
}
|
||||
|
||||
pub fn encoder<'a, 'w, W: Write>(&'a self, write: &'w mut W) -> Encoder<'w, 'a, W> {
|
||||
Encoder::new(write, self.encode_placeholders.as_ref())
|
||||
}
|
||||
|
||||
pub fn decode<R: Read>(&self, read: R) -> Result<AValue> {
|
||||
self.decoder(read).next()
|
||||
}
|
||||
|
||||
pub fn encode_bytes(&self, v: &AValue) -> Result<Vec<u8>> {
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
self.encoder(&mut buf).write(v)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
|
@ -40,21 +40,21 @@ impl Error {
|
|||
|
||||
pub type DecodePlaceholderMap = std::collections::BTreeMap<usize, Value>;
|
||||
|
||||
pub struct Decoder<R: Read> {
|
||||
pub struct Decoder<'a, R: Read> {
|
||||
read: R,
|
||||
index: usize,
|
||||
buf: Box<Option<Option<u8>>>,
|
||||
placeholders: DecodePlaceholderMap,
|
||||
placeholders: Option<&'a DecodePlaceholderMap>,
|
||||
read_annotations: bool,
|
||||
}
|
||||
|
||||
impl<R: Read> Decoder<R> {
|
||||
pub fn new(read: R, placeholders: Option<DecodePlaceholderMap>) -> Self {
|
||||
impl<'a, R: Read> Decoder<'a, R> {
|
||||
pub fn new(read: R, placeholders: Option<&'a DecodePlaceholderMap>) -> Self {
|
||||
Decoder{
|
||||
read,
|
||||
index: 0,
|
||||
buf: Box::new(None),
|
||||
placeholders: placeholders.unwrap_or(DecodePlaceholderMap::new()),
|
||||
placeholders,
|
||||
read_annotations: true,
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ impl<R: Read> Decoder<R> {
|
|||
(Op::Misc(0), _) => Err(Error::Syntax("Invalid format A encoding")),
|
||||
(Op::Misc(1), arg) => {
|
||||
let n = self.wirelength(arg)?;
|
||||
match self.placeholders.get(&n) {
|
||||
match self.placeholders.and_then(|m| m.get(&n)) {
|
||||
Some(v) => Ok(v.clone().wrap()),
|
||||
None => Err(Error::Syntax("Invalid Preserves placeholder")),
|
||||
}
|
||||
|
|
|
@ -9,17 +9,14 @@ pub type Result = std::result::Result<(), Error>;
|
|||
|
||||
pub type EncodePlaceholderMap = std::collections::BTreeMap<Value, usize>;
|
||||
|
||||
pub struct Encoder<'a, W: Write> {
|
||||
pub struct Encoder<'a, 'b, W: Write> {
|
||||
write: &'a mut W,
|
||||
placeholders: EncodePlaceholderMap,
|
||||
placeholders: Option<&'b EncodePlaceholderMap>,
|
||||
}
|
||||
|
||||
impl<'a, W: Write> Encoder<'a, W> {
|
||||
pub fn new(write: &'a mut W, placeholders: Option<EncodePlaceholderMap>) -> Self {
|
||||
Encoder{
|
||||
write,
|
||||
placeholders: placeholders.unwrap_or(EncodePlaceholderMap::new()),
|
||||
}
|
||||
impl<'a, 'b, W: Write> Encoder<'a, 'b, W> {
|
||||
pub fn new(write: &'a mut W, placeholders: Option<&'b EncodePlaceholderMap>) -> Self {
|
||||
Encoder{ write, placeholders }
|
||||
}
|
||||
|
||||
pub fn _write(&mut self, v: u8) -> Result {
|
||||
|
@ -82,7 +79,7 @@ impl<'a, W: Write> Encoder<'a, W> {
|
|||
}
|
||||
|
||||
pub fn write_value(&mut self, v: &Value) -> Result {
|
||||
match self.placeholders.get(v) {
|
||||
match self.placeholders.and_then(|m| m.get(v)) {
|
||||
Some(&n) => self.write_header(Op::Misc(1), n),
|
||||
None => match v {
|
||||
Value::Boolean(false) => self.write_op(Op::Misc(0), 0),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod codec;
|
||||
pub mod constants;
|
||||
pub mod de;
|
||||
pub mod decoder;
|
||||
|
@ -6,6 +7,7 @@ pub mod error;
|
|||
pub mod ser;
|
||||
pub mod value;
|
||||
|
||||
pub use codec::Codec;
|
||||
pub use de::Deserializer;
|
||||
pub use de::from_value;
|
||||
pub use decoder::DecodePlaceholderMap;
|
||||
|
|
Binary file not shown.
|
@ -32,7 +32,7 @@
|
|||
bytes13: <Test #hex{6f 11 61 62 63 6c 34 f0 5c 2f 22 08 0c 0a 0d 09 78 79 7a} #"abc\x6c\x34\xf0\\/\"\b\f\n\r\txyz">
|
||||
|
||||
dict0: <Test #hex{b0} {}>
|
||||
dict1: <NondeterministicTest #hex{b8 7161 31 5162 01 93313233 6163 b2 7a66697273742d6e616d65 59456c697a6162657468 b2 777375726e616d65 59426c61636b77656c6c} { a: 1 "b": #true [1 2 3]: #"c" { first-name: "Elizabeth" }: { surname: "Blackwell" } }>
|
||||
dict1: <NondeterministicTest #hex{b8 5162 01 7161 31 93313233 6163 b2 7a66697273742d6e616d65 59456c697a6162657468 b2 777375726e616d65 59426c61636b77656c6c} { a: 1 "b": #true [1 2 3]: #"c" { first-name: "Elizabeth" }: { surname: "Blackwell" } }>
|
||||
dict2: @"Missing close brace" <ParseShort "{ a: b, c: d ">
|
||||
dict2a: @"Missing close brace" <ParseShort "{">
|
||||
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
||||
|
@ -197,26 +197,26 @@
|
|||
|
||||
rfc8259-example1: <NondeterministicTest
|
||||
#hex{b2 55 496d616765
|
||||
bc 55 5469746c65
|
||||
5f14 566965772066726f6d203135746820466c6f6f72
|
||||
59 5468756d626e61696c
|
||||
b6 53 55726c
|
||||
5f26 687474703a2f2f7777772e6578616d706c652e636f6d2f696d6167652f343831393839393433
|
||||
56 486569676874
|
||||
41 7d
|
||||
55 5769647468
|
||||
41 64
|
||||
58 416e696d61746564
|
||||
bc 58 416e696d61746564
|
||||
75 66616c7365
|
||||
56 486569676874
|
||||
42 0258
|
||||
55 5769647468
|
||||
42 0320
|
||||
53 494473
|
||||
94 41 74
|
||||
42 03af
|
||||
42 00ea
|
||||
43 009789}
|
||||
43 009789
|
||||
59 5468756d626e61696c
|
||||
b6 56 486569676874
|
||||
41 7d
|
||||
53 55726c
|
||||
5f26 687474703a2f2f7777772e6578616d706c652e636f6d2f696d6167652f343831393839393433
|
||||
55 5769647468
|
||||
41 64
|
||||
55 5469746c65
|
||||
5f14 566965772066726f6d203135746820466c6f6f72
|
||||
55 5769647468
|
||||
42 0320}
|
||||
{
|
||||
"Image": {
|
||||
"Width": 800,
|
||||
|
@ -233,22 +233,22 @@
|
|||
}>
|
||||
|
||||
rfc8259-example2: <NondeterministicTest
|
||||
#hex{92 bf10 58 4c61746974756465 03 4042e226809d4952
|
||||
57 41646472657373 50
|
||||
59 707265636973696f6e 53 7a6970
|
||||
#hex{92 bf10 57 41646472657373 50
|
||||
54 43697479 5d 53414e204652414e434953434f
|
||||
57 436f756e747279 52 5553
|
||||
58 4c61746974756465 03 4042e226809d4952
|
||||
59 4c6f6e676974756465 03 c05e99566cf41f21
|
||||
55 5374617465 52 4341
|
||||
53 5a6970 55 3934313037
|
||||
54 43697479 5d 53414e204652414e434953434f
|
||||
bf10 58 4c61746974756465 03 4042af9d66adb403
|
||||
57 41646472657373 50
|
||||
59 707265636973696f6e 53 7a6970
|
||||
bf10 57 41646472657373 50
|
||||
54 43697479 59 53554e4e5956414c45
|
||||
57 436f756e747279 52 5553
|
||||
58 4c61746974756465 03 4042af9d66adb403
|
||||
59 4c6f6e676974756465 03 c05e81aa4fca42af
|
||||
55 5374617465 52 4341
|
||||
53 5a6970 55 3934303835
|
||||
54 43697479 59 53554e4e5956414c45}
|
||||
59 707265636973696f6e 53 7a6970}
|
||||
[
|
||||
{
|
||||
"precision": "zip",
|
||||
|
|
Loading…
Reference in New Issue