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)]
|
#[cfg(test)]
|
||||||
mod samples_tests {
|
mod samples_tests {
|
||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
use crate::value::Decoder;
|
use crate::value::{Codec, Decoder, codec};
|
||||||
use crate::value::{Value, AValue};
|
use crate::value::{Value, AValue};
|
||||||
use crate::value::DecodePlaceholderMap;
|
use crate::value::DecodePlaceholderMap;
|
||||||
use crate::value::to_value;
|
use crate::value::to_value;
|
||||||
use crate::value::from_value;
|
use crate::value::from_value;
|
||||||
use crate::value::invert_map;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
@ -235,20 +234,58 @@ mod samples_tests {
|
||||||
DecodeShort(#[serde(with = "serde_bytes")] Vec<u8>),
|
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 mut d = Decoder::new(std::fs::File::open("../../tests/samples.bin").unwrap(), None);
|
||||||
let tests: TestCases = from_value(&d.next().unwrap()).unwrap();
|
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!("{:#?}", 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() {
|
#[test] fn simple_to_value() {
|
||||||
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
struct SimpleValue<'a>(String,
|
struct SimpleValue<'a>(String,
|
||||||
|
#[serde(with = "crate::symbol")] String,
|
||||||
Symbol,
|
Symbol,
|
||||||
&'a str,
|
&'a str,
|
||||||
#[serde(with = "serde_bytes")] &'a [u8],
|
#[serde(with = "serde_bytes")] &'a [u8],
|
||||||
|
@ -256,7 +293,8 @@ mod samples_tests {
|
||||||
i16,
|
i16,
|
||||||
AValue);
|
AValue);
|
||||||
let v = SimpleValue("hello".to_string(),
|
let v = SimpleValue("hello".to_string(),
|
||||||
Symbol("sym".to_string()),
|
"sym1".to_string(),
|
||||||
|
Symbol("sym2".to_string()),
|
||||||
"world",
|
"world",
|
||||||
&b"slice"[..],
|
&b"slice"[..],
|
||||||
b"vec".to_vec(),
|
b"vec".to_vec(),
|
||||||
|
|
|
@ -16,3 +16,15 @@ impl<'de> serde::Deserialize<'de> for Symbol {
|
||||||
Ok(Symbol(s.clone()))
|
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 type DecodePlaceholderMap = std::collections::BTreeMap<usize, Value>;
|
||||||
|
|
||||||
pub struct Decoder<R: Read> {
|
pub struct Decoder<'a, R: Read> {
|
||||||
read: R,
|
read: R,
|
||||||
index: usize,
|
index: usize,
|
||||||
buf: Box<Option<Option<u8>>>,
|
buf: Box<Option<Option<u8>>>,
|
||||||
placeholders: DecodePlaceholderMap,
|
placeholders: Option<&'a DecodePlaceholderMap>,
|
||||||
read_annotations: bool,
|
read_annotations: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> Decoder<R> {
|
impl<'a, R: Read> Decoder<'a, R> {
|
||||||
pub fn new(read: R, placeholders: Option<DecodePlaceholderMap>) -> Self {
|
pub fn new(read: R, placeholders: Option<&'a DecodePlaceholderMap>) -> Self {
|
||||||
Decoder{
|
Decoder{
|
||||||
read,
|
read,
|
||||||
index: 0,
|
index: 0,
|
||||||
buf: Box::new(None),
|
buf: Box::new(None),
|
||||||
placeholders: placeholders.unwrap_or(DecodePlaceholderMap::new()),
|
placeholders,
|
||||||
read_annotations: true,
|
read_annotations: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ impl<R: Read> Decoder<R> {
|
||||||
(Op::Misc(0), _) => Err(Error::Syntax("Invalid format A encoding")),
|
(Op::Misc(0), _) => Err(Error::Syntax("Invalid format A encoding")),
|
||||||
(Op::Misc(1), arg) => {
|
(Op::Misc(1), arg) => {
|
||||||
let n = self.wirelength(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()),
|
Some(v) => Ok(v.clone().wrap()),
|
||||||
None => Err(Error::Syntax("Invalid Preserves placeholder")),
|
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 type EncodePlaceholderMap = std::collections::BTreeMap<Value, usize>;
|
||||||
|
|
||||||
pub struct Encoder<'a, W: Write> {
|
pub struct Encoder<'a, 'b, W: Write> {
|
||||||
write: &'a mut W,
|
write: &'a mut W,
|
||||||
placeholders: EncodePlaceholderMap,
|
placeholders: Option<&'b EncodePlaceholderMap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: Write> Encoder<'a, W> {
|
impl<'a, 'b, W: Write> Encoder<'a, 'b, W> {
|
||||||
pub fn new(write: &'a mut W, placeholders: Option<EncodePlaceholderMap>) -> Self {
|
pub fn new(write: &'a mut W, placeholders: Option<&'b EncodePlaceholderMap>) -> Self {
|
||||||
Encoder{
|
Encoder{ write, placeholders }
|
||||||
write,
|
|
||||||
placeholders: placeholders.unwrap_or(EncodePlaceholderMap::new()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _write(&mut self, v: u8) -> Result {
|
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 {
|
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),
|
Some(&n) => self.write_header(Op::Misc(1), n),
|
||||||
None => match v {
|
None => match v {
|
||||||
Value::Boolean(false) => self.write_op(Op::Misc(0), 0),
|
Value::Boolean(false) => self.write_op(Op::Misc(0), 0),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod codec;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod decoder;
|
pub mod decoder;
|
||||||
|
@ -6,6 +7,7 @@ pub mod error;
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
|
pub use codec::Codec;
|
||||||
pub use de::Deserializer;
|
pub use de::Deserializer;
|
||||||
pub use de::from_value;
|
pub use de::from_value;
|
||||||
pub use decoder::DecodePlaceholderMap;
|
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">
|
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} {}>
|
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 ">
|
dict2: @"Missing close brace" <ParseShort "{ a: b, c: d ">
|
||||||
dict2a: @"Missing close brace" <ParseShort "{">
|
dict2a: @"Missing close brace" <ParseShort "{">
|
||||||
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
||||||
|
@ -197,26 +197,26 @@
|
||||||
|
|
||||||
rfc8259-example1: <NondeterministicTest
|
rfc8259-example1: <NondeterministicTest
|
||||||
#hex{b2 55 496d616765
|
#hex{b2 55 496d616765
|
||||||
bc 55 5469746c65
|
bc 58 416e696d61746564
|
||||||
5f14 566965772066726f6d203135746820466c6f6f72
|
|
||||||
59 5468756d626e61696c
|
|
||||||
b6 53 55726c
|
|
||||||
5f26 687474703a2f2f7777772e6578616d706c652e636f6d2f696d6167652f343831393839393433
|
|
||||||
56 486569676874
|
|
||||||
41 7d
|
|
||||||
55 5769647468
|
|
||||||
41 64
|
|
||||||
58 416e696d61746564
|
|
||||||
75 66616c7365
|
75 66616c7365
|
||||||
56 486569676874
|
56 486569676874
|
||||||
42 0258
|
42 0258
|
||||||
55 5769647468
|
|
||||||
42 0320
|
|
||||||
53 494473
|
53 494473
|
||||||
94 41 74
|
94 41 74
|
||||||
42 03af
|
42 03af
|
||||||
42 00ea
|
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": {
|
"Image": {
|
||||||
"Width": 800,
|
"Width": 800,
|
||||||
|
@ -233,22 +233,22 @@
|
||||||
}>
|
}>
|
||||||
|
|
||||||
rfc8259-example2: <NondeterministicTest
|
rfc8259-example2: <NondeterministicTest
|
||||||
#hex{92 bf10 58 4c61746974756465 03 4042e226809d4952
|
#hex{92 bf10 57 41646472657373 50
|
||||||
57 41646472657373 50
|
54 43697479 5d 53414e204652414e434953434f
|
||||||
59 707265636973696f6e 53 7a6970
|
|
||||||
57 436f756e747279 52 5553
|
57 436f756e747279 52 5553
|
||||||
|
58 4c61746974756465 03 4042e226809d4952
|
||||||
59 4c6f6e676974756465 03 c05e99566cf41f21
|
59 4c6f6e676974756465 03 c05e99566cf41f21
|
||||||
55 5374617465 52 4341
|
55 5374617465 52 4341
|
||||||
53 5a6970 55 3934313037
|
53 5a6970 55 3934313037
|
||||||
54 43697479 5d 53414e204652414e434953434f
|
|
||||||
bf10 58 4c61746974756465 03 4042af9d66adb403
|
|
||||||
57 41646472657373 50
|
|
||||||
59 707265636973696f6e 53 7a6970
|
59 707265636973696f6e 53 7a6970
|
||||||
|
bf10 57 41646472657373 50
|
||||||
|
54 43697479 59 53554e4e5956414c45
|
||||||
57 436f756e747279 52 5553
|
57 436f756e747279 52 5553
|
||||||
|
58 4c61746974756465 03 4042af9d66adb403
|
||||||
59 4c6f6e676974756465 03 c05e81aa4fca42af
|
59 4c6f6e676974756465 03 c05e81aa4fca42af
|
||||||
55 5374617465 52 4341
|
55 5374617465 52 4341
|
||||||
53 5a6970 55 3934303835
|
53 5a6970 55 3934303835
|
||||||
54 43697479 59 53554e4e5956414c45}
|
59 707265636973696f6e 53 7a6970}
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"precision": "zip",
|
"precision": "zip",
|
||||||
|
|
Loading…
Reference in New Issue