Merge preserves-serde into a feature of preserves

This commit is contained in:
Tony Garnock-Jones 2022-11-22 22:57:16 +01:00
parent e1d86bd1ec
commit d01e247d04
31 changed files with 789 additions and 1013 deletions

View File

@ -3,7 +3,6 @@ members = [
"preserves",
"preserves-path",
"preserves-schema",
"preserves-serde",
"preserves-tools",
]

View File

@ -1,32 +0,0 @@
[package]
name = "preserves-serde"
version = "3.0.0"
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
edition = "2021"
description = "Serde integration with the Preserves serialization format."
homepage = "https://preserves.dev/"
repository = "https://gitlab.com/preserves/preserves"
license = "Apache-2.0"
[badges]
gitlab = { repository = "preserves/preserves" }
[dependencies]
preserves = { path = "../preserves", version = "3.0"}
base64 = "0.13"
dtoa = "0.4"
num = "0.4"
lazy_static = "1.4.0"
regex = "1.5"
serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11"
[dev-dependencies]
criterion = "0.3"
[[bench]]
name = "codec"
harness = false
[package.metadata.workspaces]
independent = true

View File

@ -1 +0,0 @@
testdata.bin

View File

@ -1,533 +0,0 @@
pub mod de;
pub mod error;
pub mod ser;
pub mod set;
pub mod symbol;
pub mod value;
#[cfg(test)]
mod dom {
use std::io;
use super::value::*;
#[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)]
pub enum Dom {
One,
Two,
}
impl Domain for Dom {
type Decode = DebugDomainCodec;
type Encode = DebugDomainCodec;
}
impl std::str::FromStr for Dom {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"One" => Ok(Dom::One),
"Two" => Ok(Dom::Two),
_ => Err(io::Error::new(io::ErrorKind::Other, "cannot parse preserves test domain")),
}
}
}
fn dom_as_preserves(v: &Dom) -> io::Result<UnwrappedIOValue> {
Ok(match v {
Dom::One => Value::bytestring(vec![255, 255, 255, 255]),
Dom::Two => Value::symbol(&format!("Dom::{:?}", v)),
})
}
#[test] fn test_one() {
let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(),
Value::Embedded(Dom::One).wrap(),
Value::from(2).wrap()])
.wrap();
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
}
#[test] fn test_two() {
let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(),
Value::Embedded(Dom::Two).wrap(),
Value::from(2).wrap()])
.wrap();
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
}
}
#[cfg(test)]
mod ieee754_section_5_10_total_order_tests {
use std::cmp::Ordering::{Less, Equal, Greater};
use super::dom::Dom;
use crate::value::{Value, PlainValue};
fn f(val: f32) -> Value<PlainValue<Dom>> { Value::from(val) }
fn d(val: f64) -> Value<PlainValue<Dom>> { Value::from(val) }
// TODO: Test cases with a few different signalling and non-signalling NaNs
#[test] fn case32_a_1() { assert_eq!(f(1.0).cmp(&f(2.0)), Less) }
#[test] fn case32_a_2() { assert_eq!(f(-1.0).cmp(&f(1.0)), Less) }
#[test] fn case32_a_3() { assert_eq!(f(0.0).cmp(&f(1.0)), Less) }
#[test] fn case32_a_4() { assert_eq!(f(-1.0).cmp(&f(0.0)), Less) }
#[test] fn case32_a_5() { assert_eq!(f(-1e32).cmp(&f(-1e31)), Less) }
#[test] fn case32_a_6() { assert_eq!(f(-1e32).cmp(&f(1e33)), Less) }
#[test] fn case32_a_7() {
assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(std::f32::INFINITY)), Less)
}
#[test] fn case32_a_8() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(0.0)), Less) }
#[test] fn case32_a_9() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(1.0)), Less) }
#[test] fn case32_a_10() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(1e33)), Less) }
#[test] fn case32_a_11() { assert_eq!(f(0.0).cmp(&f(std::f32::INFINITY)), Less) }
#[test] fn case32_a_12() { assert_eq!(f(1.0).cmp(&f(std::f32::INFINITY)), Less) }
#[test] fn case32_a_13() { assert_eq!(f(1e33).cmp(&f(std::f32::INFINITY)), Less) }
#[test] fn case32_b_1() { assert_eq!(f(2.0).cmp(&f(1.0)), Greater) }
#[test] fn case32_b_2() { assert_eq!(f(1.0).cmp(&f(-1.0)), Greater) }
#[test] fn case32_b_3() { assert_eq!(f(1.0).cmp(&f(0.0)), Greater) }
#[test] fn case32_b_4() { assert_eq!(f(0.0).cmp(&f(-1.0)), Greater) }
#[test] fn case32_b_5() { assert_eq!(f(-1e31).cmp(&f(-1e32)), Greater) }
#[test] fn case32_b_6() { assert_eq!(f(1e33).cmp(&f(-1e32)), Greater) }
#[test] fn case32_b_7() {
assert_eq!(f(std::f32::INFINITY).cmp(&f(std::f32::NEG_INFINITY)), Greater)
}
#[test] fn case32_b_8() { assert_eq!(f(std::f32::INFINITY).cmp(&f(0.0)), Greater) }
#[test] fn case32_b_9() { assert_eq!(f(std::f32::INFINITY).cmp(&f(1.0)), Greater) }
#[test] fn case32_b_10() { assert_eq!(f(std::f32::INFINITY).cmp(&f(1e33)), Greater) }
#[test] fn case32_b_11() { assert_eq!(f(0.0).cmp(&f(std::f32::NEG_INFINITY)), Greater) }
#[test] fn case32_b_12() { assert_eq!(f(1.0).cmp(&f(std::f32::NEG_INFINITY)), Greater) }
#[test] fn case32_b_13() { assert_eq!(f(1e33).cmp(&f(std::f32::NEG_INFINITY)), Greater) }
#[test] fn case32_c1() { assert_eq!(f(-0.0).cmp(&f( 0.0)), Less) }
#[test] fn case32_c2() { assert_eq!(f( 0.0).cmp(&f(-0.0)), Greater) }
#[test] fn case32_c3_1() { assert_eq!(f(-0.0).cmp(&f(-0.0)), Equal) }
#[test] fn case32_c3_2() { assert_eq!(f( 0.0).cmp(&f( 0.0)), Equal) }
#[test] fn case32_c3_3() { assert_eq!(f(1.0).cmp(&f(1.0)), Equal) }
#[test] fn case32_c3_4() { assert_eq!(f(-1.0).cmp(&f(-1.0)), Equal) }
#[test] fn case32_c3_5() { assert_eq!(f(-1e32).cmp(&f(-1e32)), Equal) }
#[test] fn case32_c3_6() { assert_eq!(f(1e33).cmp(&f(1e33)), Equal) }
#[test] fn case64_a_1() { assert_eq!(d(1.0).cmp(&d(2.0)), Less) }
#[test] fn case64_a_2() { assert_eq!(d(-1.0).cmp(&d(1.0)), Less) }
#[test] fn case64_a_3() { assert_eq!(d(0.0).cmp(&d(1.0)), Less) }
#[test] fn case64_a_4() { assert_eq!(d(-1.0).cmp(&d(0.0)), Less) }
#[test] fn case64_a_5() { assert_eq!(d(-1e32).cmp(&d(-1e31)), Less) }
#[test] fn case64_a_6() { assert_eq!(d(-1e32).cmp(&d(1e33)), Less) }
#[test] fn case64_a_7() {
assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(std::f64::INFINITY)), Less)
}
#[test] fn case64_a_8() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(0.0)), Less) }
#[test] fn case64_a_9() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(1.0)), Less) }
#[test] fn case64_a_10() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(1e33)), Less) }
#[test] fn case64_a_11() { assert_eq!(d(0.0).cmp(&d(std::f64::INFINITY)), Less) }
#[test] fn case64_a_12() { assert_eq!(d(1.0).cmp(&d(std::f64::INFINITY)), Less) }
#[test] fn case64_a_13() { assert_eq!(d(1e33).cmp(&d(std::f64::INFINITY)), Less) }
#[test] fn case64_b_1() { assert_eq!(d(2.0).cmp(&d(1.0)), Greater) }
#[test] fn case64_b_2() { assert_eq!(d(1.0).cmp(&d(-1.0)), Greater) }
#[test] fn case64_b_3() { assert_eq!(d(1.0).cmp(&d(0.0)), Greater) }
#[test] fn case64_b_4() { assert_eq!(d(0.0).cmp(&d(-1.0)), Greater) }
#[test] fn case64_b_5() { assert_eq!(d(-1e31).cmp(&d(-1e32)), Greater) }
#[test] fn case64_b_6() { assert_eq!(d(1e33).cmp(&d(-1e32)), Greater) }
#[test] fn case64_b_7() {
assert_eq!(d(std::f64::INFINITY).cmp(&d(std::f64::NEG_INFINITY)), Greater)
}
#[test] fn case64_b_8() { assert_eq!(d(std::f64::INFINITY).cmp(&d(0.0)), Greater) }
#[test] fn case64_b_9() { assert_eq!(d(std::f64::INFINITY).cmp(&d(1.0)), Greater) }
#[test] fn case64_b_10() { assert_eq!(d(std::f64::INFINITY).cmp(&d(1e33)), Greater) }
#[test] fn case64_b_11() { assert_eq!(d(0.0).cmp(&d(std::f64::NEG_INFINITY)), Greater) }
#[test] fn case64_b_12() { assert_eq!(d(1.0).cmp(&d(std::f64::NEG_INFINITY)), Greater) }
#[test] fn case64_b_13() { assert_eq!(d(1e33).cmp(&d(std::f64::NEG_INFINITY)), Greater) }
#[test] fn case64_c1() { assert_eq!(d(-0.0).cmp(&d( 0.0)), Less) }
#[test] fn case64_c2() { assert_eq!(d( 0.0).cmp(&d(-0.0)), Greater) }
#[test] fn case64_c3_1() { assert_eq!(d(-0.0).cmp(&d(-0.0)), Equal) }
#[test] fn case64_c3_2() { assert_eq!(d( 0.0).cmp(&d( 0.0)), Equal) }
#[test] fn case64_c3_3() { assert_eq!(d(1.0).cmp(&d(1.0)), Equal) }
#[test] fn case64_c3_4() { assert_eq!(d(-1.0).cmp(&d(-1.0)), Equal) }
#[test] fn case64_c3_5() { assert_eq!(d(-1e32).cmp(&d(-1e32)), Equal) }
#[test] fn case64_c3_6() { assert_eq!(d(1e33).cmp(&d(1e33)), Equal) }
}
#[cfg(test)]
mod value_tests {
use crate::value::{Value, PlainValue, repr::Record, signed_integer::SignedInteger};
use super::dom::Dom;
type VV = Value<PlainValue<Dom>>;
#[test] fn boolean_mut() {
let mut b = VV::Boolean(true);
assert!(b.is_boolean());
*(b.as_boolean_mut().unwrap()) = false;
assert_eq!(b, VV::Boolean(false));
}
#[test] fn float_mut() {
let mut f = VV::from(1.0f32);
assert!(f.is_f32());
*(f.as_f32_mut().unwrap()) = 123.45;
assert_eq!(f, VV::from(123.45f32));
assert_eq!((f.as_f32().unwrap() - 123.45f32).abs() < std::f32::EPSILON, true);
}
#[test] fn double_mut() {
let mut f = VV::from(1.0);
assert!(f.is_f64());
*(f.as_f64_mut().unwrap()) = 123.45;
assert_eq!(f, VV::from(123.45));
assert_eq!((f.as_f64().unwrap() - 123.45).abs() < std::f64::EPSILON, true);
}
#[test] fn signedinteger_mut() {
let mut i = VV::from(123);
assert!(i.is_signedinteger());
*(i.as_signedinteger_mut().unwrap()) = SignedInteger::from(234i128);
assert_eq!(i, VV::from(234));
assert_eq!(i.as_i().unwrap(), 234);
}
#[test] fn string_mut() {
let mut s = VV::from("hello, world!");
assert!(s.is_string());
s.as_string_mut().unwrap().replace_range(7..12, "there");
assert_eq!(s, VV::from("hello, there!"));
}
#[test] fn bytes_mut() {
let mut b = VV::from(&b"hello, world!"[..]);
assert!(b.is_bytestring());
b.as_bytestring_mut().unwrap().splice(7..12, Vec::from(&b"there"[..]));
assert_eq!(b, VV::from(&b"hello, there!"[..]));
}
#[test] fn symbol_mut() {
let mut s = VV::symbol("abcd");
assert!(s.is_symbol());
s.as_symbol_mut().unwrap().replace_range(..2, "AB");
assert_eq!(s, VV::symbol("ABcd"));
}
#[test] fn record_mut() {
let says = VV::symbol("says").wrap();
let mut r = VV::Record(Record(vec![says.clone(), VV::from("Tony").wrap(), VV::from("Hello!").wrap()]));
assert_eq!(r.as_record_mut(Some(0)), None);
assert_eq!(r.as_record_mut(Some(1)), None);
assert!(r.as_record_mut(Some(2)).is_some());
assert_eq!(r.as_record_mut(Some(3)), None);
r.as_record_mut(None).unwrap().fields_mut()[0] = VV::from("Alice").wrap();
assert_eq!(r, VV::Record(Record(vec![says, VV::from("Alice").wrap(), VV::from("Hello!").wrap()])));
}
#[test] fn sequence_mut() {
let mut s = VV::Sequence(vec![VV::from(1).wrap(),
VV::from(2).wrap(),
VV::from(3).wrap()]);
let r = VV::Sequence(vec![VV::from(1).wrap(),
VV::from(99).wrap(),
VV::from(3).wrap()]);
s.as_sequence_mut().unwrap()[1] = VV::from(99).wrap();
assert_eq!(r, s);
}
}
#[cfg(test)]
mod decoder_tests {
use crate::value::{Value, BinarySource, IOValue, NestedValue, BytesBinarySource, ConfiguredReader};
use crate::de::from_bytes;
use crate::error::{Error, ExpectedKind, is_eof_io_error};
fn expect_number_out_of_range<T: core::fmt::Debug>(r: Result<T, Error>) {
match r {
Ok(v) => panic!("Expected NumberOutOfRange, but got a parse of {:?}", v),
Err(Error::NumberOutOfRange(_)) => (),
Err(e) => panic!("Expected NumberOutOfRange, but got an error of {:?}", e),
}
}
fn expect_expected<T: core::fmt::Debug>(k: ExpectedKind, r: Result<T, Error>) {
match r {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
Err(Error::Expected(k1)) if k1 == k => (),
Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
}
}
#[test] fn skip_annotations_noskip() {
let buf = &b"\x85\x92\x91"[..];
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new_default(src.packed());
let v: IOValue = d.demand_next().unwrap();
assert_eq!(v.annotations().unwrap().len(), 1);
assert_eq!(v.annotations().unwrap()[0], Value::from(2).wrap());
assert_eq!(v.value(), &Value::from(1));
}
#[test] fn skip_annotations_skip() {
let buf = &b"\x85\x92\x91"[..];
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new_default(src.packed()).read_annotations(false);
let v: IOValue = d.demand_next().unwrap();
assert!(v.annotations().is_none());
assert_eq!(v.value(), &Value::from(1));
}
#[test] fn multiple_values_buf_advanced() {
let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 16);
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::<IOValue, _, _>::new_default(src.packed());
assert_eq!(d.reader.source.index, 0);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
assert_eq!(d.reader.source.index, 8);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
assert_eq!(d.reader.source.index, 16);
assert!(d.next().is_none());
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
}
#[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"\x91").unwrap(), 1) }
#[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"\x90").unwrap(), 0) }
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\x9f").unwrap(), -1) }
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa0\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"\xa2\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"\x91").unwrap(), 1) }
#[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"\x90").unwrap(), 0) }
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa01").unwrap(), 49) }
#[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\01").unwrap(), 49) }
#[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xa9\0\0\0\0\0\0\0\0\01").unwrap(), 49) }
#[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b"\x9e").unwrap(), -2) }
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa1\xfe\xff").unwrap(), -257) }
#[test] fn direct_u8_wrong_format() {
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xb1\x05bogus"))
}
#[test] fn direct_u8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<u8>(b"\xa3\0\011"))
}
#[test] fn direct_i8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i8>(b"\xa1\xfe\xff"))
}
#[test] fn direct_i16_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i16>(b"\xa2\xfe\xff\xff"));
}
#[test] fn direct_i32_format_b_ok() {
assert_eq!(from_bytes::<i32>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
}
#[test] fn direct_i32_format_b_ok_2() {
assert_eq!(from_bytes::<i32>(b"\xa3\xfe\xff\xff\xff").unwrap(), -16777217);
}
#[test] fn direct_i64_format_b() {
assert_eq!(from_bytes::<i64>(b"\xa0\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa0\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
expect_number_out_of_range(from_bytes::<i64>(b"\xa9\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa8\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa8\x80\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa9\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<i64>(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
assert_eq!(from_bytes::<i64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
assert_eq!(from_bytes::<i64>(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
assert_eq!(from_bytes::<i64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
}
#[test] fn direct_u64_format_b() {
expect_number_out_of_range(from_bytes::<u64>(b"\xa0\xff"));
assert_eq!(from_bytes::<u64>(b"\xa1\0\xff").unwrap(), 255);
expect_number_out_of_range(from_bytes::<u64>(b"\xa2\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff);
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa0\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"\xa2\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"\xa2\x01\x00\x00").unwrap(), 65536);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa8\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"\xa8\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
expect_number_out_of_range(from_bytes::<u64>(b"\xa9\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
expect_number_out_of_range(from_bytes::<u64>(b"\xa7\x80\0\0\0\0\0\0\0"));
assert_eq!(from_bytes::<u64>(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
assert_eq!(from_bytes::<u64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
}
}
#[cfg(test)]
mod formatting_tests {
use super::dom::Dom;
use super::value::ArcValue;
use super::value::IOValue;
use super::value::Value;
#[test] fn format_debug_and_parse() {
let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::<Value<ArcValue<Dom>>>().unwrap();
assert_eq!(format!("{:?}", &v), "[1, {a: #!\"One\", z: 2}, 3]");
}
#[test] fn format_pretty_debug_and_parse() {
let v = "[1, {z: 2, a: #!\"One\"}, 3]".parse::<Value<ArcValue<Dom>>>().unwrap();
assert_eq!(format!("{:#?}", &v), concat!(
"[\n",
" 1,\n",
" {\n",
" a: #!\"One\",\n",
" z: 2\n",
" },\n",
" 3\n",
"]"));
}
#[test] fn iovalue_parse() {
let v = "[1 @{a:b c:d} @\"foo\" #![2 3] 4]".parse::<IOValue>().unwrap();
assert_eq!(format!("{:#?}", &v), concat!(
"[\n",
" 1,\n",
" @{\n",
" a: b,\n",
" c: d\n",
" } @\"foo\" #![\n",
" 2,\n",
" 3\n",
" ],\n",
" 4\n",
"]"));
}
}
#[cfg(test)]
mod serde_tests {
use crate::symbol::Symbol;
use crate::de::from_bytes as deserialize_from_bytes;
use crate::value::de::from_value as deserialize_from_value;
use crate::value::to_value;
use crate::value::{Value, IOValue, Map, Set};
use crate::value::packed::PackedWriter;
#[test] fn simple_to_value() {
use serde::Serialize;
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
struct Colour{ red: u8, green: u8, blue: u8 }
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
struct SimpleValue<'a>(String,
#[serde(with = "crate::symbol")] String,
Symbol,
#[serde(with = "crate::symbol")] String,
Symbol,
&'a str,
#[serde(with = "serde_bytes")] &'a [u8],
#[serde(with = "serde_bytes")] Vec<u8>,
Vec<bool>,
#[serde(with = "crate::set")] Set<String>,
i16,
IOValue,
Map<String, Colour>,
f32,
f64);
let mut str_set = Set::new();
str_set.insert("one".to_owned());
str_set.insert("two".to_owned());
str_set.insert("three".to_owned());
let mut colours = Map::new();
colours.insert("red".to_owned(), Colour { red: 255, green: 0, blue: 0 });
colours.insert("green".to_owned(), Colour { red: 0, green: 255, blue: 0 });
colours.insert("blue".to_owned(), Colour { red: 0, green: 0, blue: 255 });
let v = SimpleValue("hello".to_string(),
"sym1".to_string(),
Symbol("sym2".to_string()),
"sym3".to_string(),
Symbol("sym4".to_string()),
"world",
&b"slice"[..],
b"vec".to_vec(),
vec![false, true, false, true],
str_set,
12345,
Value::from("hi").wrap(),
colours,
12.345,
12.3456789);
println!("== v: {:#?}", v);
let w: IOValue = to_value(&v);
println!("== w: {:#?}", w);
let x = deserialize_from_value(&w).unwrap();
println!("== x: {:#?}", &x);
assert_eq!(v, x);
let expected_bytes = vec![
0xb4, // Struct
0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4
0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec"
0xb5, // Sequence
0x80, // false
0x81, // true
0x80, // false
0x81, // true
0x84,
0xb6, // Set
0xb1, 0x03, 0x6f, 0x6e, 0x65,
0xb1, 0x03, 0x74, 0x77, 0x6f,
0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65,
0x84,
0xa1, 0x30, 0x39, // 12345
0xb1, 0x02, 0x68, 0x69, // "hi"
0xb7, // Dictionary
0xb1, 0x03, 0x72, 0x65, 0x64, // "red"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84,
0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0x90, 0xa1, 0x00, 0xff, 0x84,
0xb1, 0x05, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0xa1, 0x00, 0xff, 0x90, 0x84,
0x84,
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
0x84,
];
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let v_bytes_1 = PackedWriter::encode_iovalue(&w).unwrap();
println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1);
let mut v_bytes_2 = Vec::new();
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
println!("== v bytes = {:?}", v_bytes_2);
assert_eq!(v_bytes_1, v_bytes_2);
}
}

View File

@ -1,352 +0,0 @@
use preserves::{Value, IOValue, Map, ValueImpl};
use crate::error::Error;
use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::iter::Iterator;
pub type Result<T> = std::result::Result<T, Error>;
pub struct Deserializer<'de, D> {
input: Value<'de, D>,
}
pub fn from_value<'de, T>(v: &'de IOValue) -> Result<T> where T: Deserialize<'de>
{
let mut de = Deserializer::from_value(v);
let t = T::deserialize(&mut de)?;
Ok(t)
}
impl<'de> Deserializer<'de> {
pub fn from_value(v: &'de IOValue) -> Self {
Deserializer { input: v }
}
}
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
{
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let v = self.input.value();
match v {
Value::Boolean(b) => visitor.visit_bool(*b),
Value::Float(f) => visitor.visit_f32(*f),
Value::Double(d) => visitor.visit_f64(*d),
Value::String(s) => visitor.visit_str(&s),
Value::ByteString(_) => self.deserialize_bytes(visitor),
Value::Record(_) =>
if v.is_simple_record("tuple", Some(0)) {
self.deserialize_unit(visitor)
} else if v.is_simple_record("UnicodeScalar", Some(1)) {
self.deserialize_char(visitor)
} else if v.is_simple_record("None", Some(0)) || v.is_simple_record("Some", Some(1)) {
self.deserialize_option(visitor)
} else if v.is_simple_record("tuple", None) {
visitor.visit_seq(VecSeq::new(self, v.as_simple_record("tuple", None).unwrap().iter()))
} else {
Err(Error::CannotDeserializeAny)
}
Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v.iter())),
Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)),
_ => match v.as_i64() {
Some(i) => visitor.visit_i64(i),
None => match v.as_u64() {
Some(u) => visitor.visit_u64(u),
None => match v.as_signedinteger() {
Some(n) => Err(Error::NumberOutOfRange(n.into())),
None => Err(Error::CannotDeserializeAny),
}
}
}
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_bool(self.input.value().to_boolean()?)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i8(self.input.value().to_i8()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i16(self.input.value().to_i16()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i32(self.input.value().to_i32()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i64(self.input.value().to_i64()?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u8(self.input.value().to_u8()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u16(self.input.value().to_u16()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u32(self.input.value().to_u32()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u64(self.input.value().to_u64()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
match self.input.value().as_f64() {
Some(d) => visitor.visit_f32(d as f32),
None => visitor.visit_f32(self.input.value().to_f32()?),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
match self.input.value().as_f32() {
Some(f) => visitor.visit_f64(f as f64),
None => visitor.visit_f64(self.input.value().to_f64()?),
}
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_char(self.input.value().to_char()?)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_borrowed_str(self.input.value().to_string()?)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
self.deserialize_str(visitor)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_borrowed_bytes(self.input.value().to_bytestring()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_byte_buf(self.input.value().to_bytestring()?.clone())
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
match self.input.value().to_option()? {
None => visitor.visit_none(),
Some(v) => {
self.input = v;
visitor.visit_some(self)
}
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let _fs = self.input.value().to_simple_record("tuple", Some(0))?;
visitor.visit_unit()
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let _fs = self.input.value().to_simple_record(name, Some(0))?;
visitor.visit_unit()
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
match super::magic::transmit_input_value(name, || Ok(self.input.clone()))? {
Some(v) => visitor.visit_u64(v),
None => {
let fs = self.input.value().to_simple_record(name, Some(1))?;
self.input = &fs[0];
visitor.visit_newtype_struct(self)
}
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
match self.input.value().as_sequence() {
Some(vs) => visitor.visit_seq(VecSeq::new(self, vs.iter())),
None => {
// Hack around serde's model: Deserialize *sets* as
// sequences, too, and reconstruct them as Rust Sets
// on the visitor side.
visitor.visit_seq(VecSeq::new(self, self.input.value().to_set()?.iter()))
}
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let fs = self.input.value().to_simple_record("tuple", Some(len))?;
visitor.visit_seq(VecSeq::new(self, fs.iter()))
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let fs = self.input.value().to_simple_record(name, Some(len))?;
visitor.visit_seq(VecSeq::new(self, fs.iter()))
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
let d = self.input.value().to_dictionary()?;
visitor.visit_map(DictMap::new(self, d))
}
fn deserialize_struct<V>(self,
name: &'static str,
fields: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let fs = self.input.value().to_simple_record(name, Some(fields.len()))?;
visitor.visit_seq(VecSeq::new(self, fs.iter()))
}
fn deserialize_enum<V>(self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_enum(self)
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_str(&self.input.value().to_symbol()?)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_none()
}
}
pub struct VecSeq<'a, 'de: 'a, I: Iterator<Item = &'de IOValue>> {
iter: I,
de: &'a mut Deserializer<'de>,
}
impl<'de, 'a, I: Iterator<Item = &'de IOValue>> VecSeq<'a, 'de, I> {
fn new(de: &'a mut Deserializer<'de>, iter: I) -> Self {
VecSeq { iter, de }
}
}
impl<'de, 'a, I: Iterator<Item = &'de IOValue>> SeqAccess<'de> for VecSeq<'a, 'de, I> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) ->
Result<Option<T::Value>>
where
T: DeserializeSeed<'de>
{
match self.iter.next() {
None => Ok(None),
Some(v) => {
self.de.input = v;
Ok(Some(seed.deserialize(&mut *self.de)?))
}
}
}
}
pub struct DictMap<'a, 'de: 'a> {
pending: Option<&'de IOValue>,
iter: Box<dyn Iterator<Item = (&'de IOValue, &'de IOValue)> + 'a>,
de: &'a mut Deserializer<'de>,
}
impl<'de, 'a> DictMap<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self {
DictMap{ pending: None, iter: Box::new(d.iter()), de }
}
}
impl<'de, 'a> MapAccess<'de> for DictMap<'a, 'de> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K)
-> Result<Option<K::Value>> where K: DeserializeSeed<'de>
{
match self.iter.next() {
None => Ok(None),
Some((k, v)) => {
self.pending = Some(v);
self.de.input = k;
Ok(Some(seed.deserialize(&mut *self.de)?))
}
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> where V: DeserializeSeed<'de> {
let v = self.pending.unwrap();
self.pending = None;
self.de.input = v;
Ok(seed.deserialize(&mut *self.de)?)
}
}
impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{
let r = self.input.value().to_record(None)?;
let v = self.input;
self.input = r.label();
let variant = seed.deserialize(&mut *self)?;
self.input = v;
Ok((variant, self))
}
}
impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
let r = self.input.value().to_record(Some(1))?;
self.input = &r.fields()[0];
seed.deserialize(&mut *self)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(None).unwrap().fields().iter()))
}
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(Some(fields.len())).unwrap().fields().iter()))
}
}

View File

@ -1,29 +0,0 @@
pub mod de;
pub mod magic;
pub mod ser;
pub mod merge;
pub use de::Deserializer;
pub use de::from_value;
pub use merge::merge;
pub use ser::Serializer;
pub use ser::to_value;
// https://stackoverflow.com/questions/34304593/counting-length-of-repetition-in-macro/34324856
#[macro_export]
//#[allow(unused_macros)]
macro_rules! count__ {
() => (0usize);
( $x:tt $($xs:tt)* ) => (1usize + $crate::count__!($($xs)*));
}
#[macro_export]
macro_rules! rec {
( $label:expr $(, $item:expr)* ) => {
{
let mut r__ = $crate::value::Value::record($label, $crate::count__!($($item)*));
$(r__.fields_vec_mut().push($item);)*
r__.finish().wrap()
}
}
}

View File

@ -20,6 +20,9 @@ num-bigint = "0.4"
num-traits = "0.2"
regex = "1.5"
serde = { version = "1.0", features = ["derive"], optional = true }
serde_bytes = { version = "0.11", optional = true }
[dev-dependencies]
criterion = "0.3"
@ -29,3 +32,7 @@ harness = false
[package.metadata.workspaces]
independent = true
[features]
default = ["serde"]
serde = ["dep:serde", "dep:serde_bytes"]

View File

@ -14,6 +14,7 @@ use crate::Reader;
use crate::DomainEncode;
use crate::Record;
use crate::SignedInteger;
use crate::Symbol;
use crate::Value;
use crate::ValueClass;
use crate::ValueImpl;
@ -57,6 +58,10 @@ impl IOValue {
fields.into_iter().map(|f| f.into()).collect()))
}
pub fn symbol(s: &str) -> Self {
Self::new(Symbol::new(s.to_owned()))
}
pub fn value(&self) -> &IOValueImpl {
&self.0
}
@ -228,7 +233,7 @@ impl<'de, R: Reader<'de>> IOValues<'de, R> {
pub fn new(reader: R) -> Self {
IOValues {
reader,
read_annotations: false,
read_annotations: true,
phantom: PhantomData,
}
}

View File

@ -16,6 +16,9 @@ pub mod text;
pub mod types;
pub mod writer;
#[cfg(feature = "serde")]
pub mod serde;
pub use atom::Atom;
pub use domain::*;
pub use error::Error;

View File

@ -16,6 +16,7 @@ use crate::DefaultDomainCodec;
use crate::Domain;
use crate::DomainEncode;
use crate::Embedded;
use crate::ExpectedKind;
use crate::IOValue;
use crate::Map;
use crate::Record;
@ -89,6 +90,35 @@ pub trait ValueImpl<D: Domain> {
fn annotations(&self) -> Option<Cow<'_, [IOValue]>> { None }
fn peeled(self: Arc<Self>) -> Value<D>;
//---------------------------------------------------------------------------
fn to_boolean(&self) -> Result<bool, ExpectedKind> { self.as_boolean().ok_or(ExpectedKind::Boolean) }
fn to_float(&self) -> Result<f32, ExpectedKind> { self.as_float().ok_or(ExpectedKind::Float) }
fn to_double(&self) -> Result<f64, ExpectedKind> { self.as_double().ok_or(ExpectedKind::Double) }
fn to_signed_integer(&self) -> Result<Cow<'_, SignedInteger>, ExpectedKind> { self.as_signed_integer().ok_or(ExpectedKind::SignedInteger) }
fn to_str/*ing*/(&self) -> Result<Cow<'_, str>, ExpectedKind> { self.as_string().ok_or(ExpectedKind::String) }
fn to_bytestring(&self) -> Result<Cow<'_, [u8]>, ExpectedKind> { self.as_bytestring().ok_or(ExpectedKind::ByteString) }
fn to_symbol(&self) -> Result<Cow<'_, str>, ExpectedKind> { self.as_symbol().ok_or(ExpectedKind::Symbol) }
fn to_i8(&self) -> Result<Result<i8, OutOfRange>, ExpectedKind> { self.as_i8().ok_or(ExpectedKind::SignedInteger) }
fn to_u8(&self) -> Result<Result<u8, OutOfRange>, ExpectedKind> { self.as_u8().ok_or(ExpectedKind::SignedInteger) }
fn to_i16(&self) -> Result<Result<i16, OutOfRange>, ExpectedKind> { self.as_i16().ok_or(ExpectedKind::SignedInteger) }
fn to_u16(&self) -> Result<Result<u16, OutOfRange>, ExpectedKind> { self.as_u16().ok_or(ExpectedKind::SignedInteger) }
fn to_i32(&self) -> Result<Result<i32, OutOfRange>, ExpectedKind> { self.as_i32().ok_or(ExpectedKind::SignedInteger) }
fn to_u32(&self) -> Result<Result<u32, OutOfRange>, ExpectedKind> { self.as_u32().ok_or(ExpectedKind::SignedInteger) }
fn to_i64(&self) -> Result<Result<i64, OutOfRange>, ExpectedKind> { self.as_i64().ok_or(ExpectedKind::SignedInteger) }
fn to_u64(&self) -> Result<Result<u64, OutOfRange>, ExpectedKind> { self.as_u64().ok_or(ExpectedKind::SignedInteger) }
fn to_i128(&self) -> Result<Result<i128, OutOfRange>, ExpectedKind> { self.as_i128().ok_or(ExpectedKind::SignedInteger) }
fn to_u128(&self) -> Result<Result<u128, OutOfRange>, ExpectedKind> { self.as_u128().ok_or(ExpectedKind::SignedInteger) }
fn to_isize(&self) -> Result<Result<isize, OutOfRange>, ExpectedKind> { self.as_isize().ok_or(ExpectedKind::SignedInteger) }
fn to_usize(&self) -> Result<Result<usize, OutOfRange>, ExpectedKind> { self.as_usize().ok_or(ExpectedKind::SignedInteger) }
fn is_simple_record(&self, name: &str, arity: Option<usize>) -> bool {
self.is_record() &&
self.label().as_symbol().map(|l| l.as_ref()) == Some(name) &&
(arity.is_none() || arity.unwrap() == self.len())
}
}
impl<D: Domain> Deref for Value<D> {

View File

@ -5,13 +5,15 @@ use std::borrow::Cow;
use std::io;
use std::marker::PhantomData;
use super::value::boundary as B;
use super::value::{PackedReader, TextReader};
use super::value::reader::Reader;
use super::value::source::BytesBinarySource;
use super::value::source::IOBinarySource;
use crate::boundary as B;
use crate::PackedReader;
use crate::TextReader;
use crate::Reader;
use crate::BytesBinarySource;
use crate::IOBinarySource;
use crate::ExpectedKind;
pub use super::error::{Error, ExpectedKind};
pub use super::error::Error;
pub type Result<T> = std::result::Result<T, Error>;

View File

@ -1,9 +1,11 @@
use std::convert::From;
use std::io;
use crate::signed_integer::OutOfRange;
#[derive(Debug)]
pub enum Error {
Preserves(preserves::Error),
Preserves(crate::Error),
Message(String),
InvalidUnicodeScalar(u32),
CannotDeserializeAny,
@ -11,12 +13,24 @@ pub enum Error {
ExpectedUnicodeScalar,
}
impl From<preserves::Error> for Error {
fn from(e: io::Error) -> Self {
impl From<crate::Error> for Error {
fn from(e: crate::Error) -> Self {
Error::Preserves(e)
}
}
impl From<crate::ExpectedKind> for Error {
fn from(k: crate::ExpectedKind) -> Self {
crate::Error::Expected(k).into()
}
}
impl From<OutOfRange> for Error {
fn from(o: OutOfRange) -> Self {
crate::Error::from(o).into()
}
}
impl From<Error> for io::Error {
fn from(e: Error) -> Self {
match e {

View File

@ -0,0 +1,256 @@
pub mod de;
pub mod error;
pub mod ser;
pub mod set;
pub mod symbol;
pub mod value;
pub use error::Error;
pub use value::from_value;
pub use value::to_value;
#[cfg(test)]
mod decoder_tests {
use crate::*;
use crate::serde::*;
use crate::serde::de::from_bytes;
use std::fmt::Debug;
fn expect_number_out_of_range<T: Debug>(r: Result<T, crate::serde::Error>) {
match r {
Ok(v) => panic!("Expected NumberOutOfRange, but got a parse of {:?}", v),
Err(crate::serde::Error::Preserves(crate::Error::NumberOutOfRange(_))) => (),
Err(e) => panic!("Expected NumberOutOfRange, but got an error of {:?}", e),
}
}
fn expect_expected<T: Debug>(k: ExpectedKind, r: Result<T, crate::serde::Error>) {
match r {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
Err(crate::serde::Error::Preserves(crate::Error::Expected(k1))) if k1 == k => (),
Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
}
}
#[test] fn skip_annotations_noskip() {
let v: IOValue = IOValue::from_bytes(b"\x85\x92\x91", true).unwrap().into();
assert_eq!(v.annotations().unwrap().len(), 1);
assert_eq!(v.annotations().unwrap()[0], IOValue::new(2));
assert_eq!(v, IOValue::new(1));
}
#[test] fn skip_annotations_skip() {
let v: IOValue = IOValue::from_bytes(b"\x85\x92\x91", false).unwrap().into();
assert!(v.annotations().is_none());
assert_eq!(v, IOValue::new(1));
}
#[test] fn multiple_values_buf_advanced() {
let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 16);
let mut d = IOValues::new(BytesBinarySource::new(&buf).packed());
assert_eq!(d.reader.source.index, 0);
assert_eq!(d.next().unwrap().unwrap(), IOValue::record(IOValue::symbol("Ping"), vec![]));
assert_eq!(d.reader.source.index, 8);
assert_eq!(d.next().unwrap().unwrap(), IOValue::record(IOValue::symbol("Pong"), vec![]));
assert_eq!(d.reader.source.index, 16);
assert!(d.next().is_none());
}
#[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"\x91").unwrap(), 1) }
#[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"\x90").unwrap(), 0) }
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\x9f").unwrap(), -1) }
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa0\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"\xa2\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"\x91").unwrap(), 1) }
#[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"\x90").unwrap(), 0) }
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa01").unwrap(), 49) }
#[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\01").unwrap(), 49) }
#[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xa9\0\0\0\0\0\0\0\0\01").unwrap(), 49) }
#[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b"\x9e").unwrap(), -2) }
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa1\xfe\xff").unwrap(), -257) }
#[test] fn direct_u8_wrong_format() {
expect_expected::<u8>(ExpectedKind::SignedInteger, from_bytes(b"\xb1\x05bogus"))
}
#[test] fn direct_u8_format_b_too_large() {
expect_number_out_of_range::<u8>(from_bytes(b"\xa3\0\011"))
}
#[test] fn direct_i8_format_b_too_large() {
expect_number_out_of_range::<i8>(from_bytes(b"\xa1\xfe\xff"))
}
#[test] fn direct_i16_format_b_too_large() {
expect_number_out_of_range::<i16>(from_bytes(b"\xa2\xfe\xff\xff"));
}
#[test] fn direct_i32_format_b_ok() {
assert_eq!(from_bytes::<i32>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
}
#[test] fn direct_i32_format_b_ok_2() {
assert_eq!(from_bytes::<i32>(b"\xa3\xfe\xff\xff\xff").unwrap(), -16777217);
}
#[test] fn direct_i64_format_b() {
assert_eq!(from_bytes::<i64>(b"\xa0\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa0\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
expect_number_out_of_range::<i64>(from_bytes(b"\xa9\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range::<i64>(from_bytes(b"\xa8\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range::<i64>(from_bytes(b"\xa8\x80\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range::<i64>(from_bytes(b"\xa9\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<i64>(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
assert_eq!(from_bytes::<i64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
assert_eq!(from_bytes::<i64>(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
assert_eq!(from_bytes::<i64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
}
#[test] fn direct_u64_format_b() {
expect_number_out_of_range::<u64>(from_bytes(b"\xa0\xff"));
assert_eq!(from_bytes::<u64>(b"\xa1\0\xff").unwrap(), 255);
expect_number_out_of_range::<u64>(from_bytes(b"\xa2\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff);
expect_number_out_of_range::<u64>(from_bytes(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa0\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"\xa2\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"\xa2\x01\x00\x00").unwrap(), 65536);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
expect_number_out_of_range::<u64>(from_bytes(b"\xa9\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa8\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
expect_number_out_of_range::<u64>(from_bytes(b"\xa8\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
expect_number_out_of_range::<u64>(from_bytes(b"\xa9\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
expect_number_out_of_range::<u64>(from_bytes(b"\xa7\x80\0\0\0\0\0\0\0"));
assert_eq!(from_bytes::<u64>(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
assert_eq!(from_bytes::<u64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
}
}
#[cfg(test)]
mod serde_tests {
use crate::*;
use super::de::from_bytes as deserialize_from_bytes;
use super::value::de::from_value as deserialize_from_value;
use super::value::to_value;
#[test] fn simple_to_value() {
use ::serde::Serialize;
#[derive(Debug, PartialEq, Eq, ::serde::Serialize, ::serde::Deserialize)]
struct Colour{ red: u8, green: u8, blue: u8 }
#[derive(Debug, PartialEq, ::serde::Serialize, ::serde::Deserialize)]
struct SimpleValue<'a>(String,
#[serde(with = "crate::serde::symbol")] String,
Symbol,
#[serde(with = "crate::serde::symbol")] String,
Symbol,
&'a str,
#[serde(with = "serde_bytes")] &'a [u8],
#[serde(with = "serde_bytes")] Vec<u8>,
Vec<bool>,
#[serde(with = "crate::serde::set")] Set<String>,
i16,
IOValue,
Map<String, Colour>,
f32,
f64);
let mut str_set = Set::new();
str_set.insert("one".to_owned());
str_set.insert("two".to_owned());
str_set.insert("three".to_owned());
let mut colours = Map::new();
colours.insert("red".to_owned(), Colour { red: 255, green: 0, blue: 0 });
colours.insert("green".to_owned(), Colour { red: 0, green: 255, blue: 0 });
colours.insert("blue".to_owned(), Colour { red: 0, green: 0, blue: 255 });
let v = SimpleValue("hello".to_string(),
"sym1".to_string(),
Symbol::new("sym2".to_string()),
"sym3".to_string(),
Symbol::new("sym4".to_string()),
"world",
&b"slice"[..],
b"vec".to_vec(),
vec![false, true, false, true],
str_set,
12345,
IOValue::new("hi"),
colours,
12.345,
12.3456789);
println!("== v: {:#?}", v);
let w: IOValue = to_value(&v);
println!("== w: {:#?}", w);
let x = deserialize_from_value(&w).unwrap();
println!("== x: {:#?}", &x);
assert_eq!(v, x);
let expected_bytes = vec![
0xb4, // Struct
0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4
0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec"
0xb5, // Sequence
0x80, // false
0x81, // true
0x80, // false
0x81, // true
0x84,
0xb6, // Set
0xb1, 0x03, 0x6f, 0x6e, 0x65,
0xb1, 0x03, 0x74, 0x77, 0x6f,
0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65,
0x84,
0xa1, 0x30, 0x39, // 12345
0xb1, 0x02, 0x68, 0x69, // "hi"
0xb7, // Dictionary
0xb1, 0x03, 0x72, 0x65, 0x64, // "red"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84,
0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0x90, 0xa1, 0x00, 0xff, 0x84,
0xb1, 0x05, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0xa1, 0x00, 0xff, 0x90, 0x84,
0x84,
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
0x84,
];
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let v_bytes_1 = PackedWriter::encode(&w).unwrap();
println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1);
let mut v_bytes_2 = Vec::new();
v.serialize(&mut crate::serde::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
println!("== v bytes = {:?}", v_bytes_2);
assert_eq!(v_bytes_1, v_bytes_2);
}
}

View File

@ -1,7 +1,7 @@
use serde::Serialize;
use super::value::IOValueDomainCodec;
use super::value::boundary as B;
use super::value::writer::Writer;
use crate::IOValueDomainEncode;
use crate::Writer;
use crate::boundary as B;
use ::serde::Serialize;
pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>;
@ -158,7 +158,7 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Result<Self::Ok> where T: Serialize
{
match super::value::magic::receive_output_value(name, value) {
Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
Some(v) => Ok(self.write.write(&mut IOValueDomainEncode, &v)?),
None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
self.write.start_record()?;

View File

@ -1,15 +1,17 @@
use crate::value::{self, to_value, IOValue, UnwrappedIOValue};
use crate::{IOValue, Set};
use std::iter::IntoIterator;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use super::to_value;
pub fn serialize<S, T, Item>(s: T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: IntoIterator<Item = Item>,
Item: Serialize,
{
let s = s.into_iter().map(to_value).collect::<value::Set<IOValue>>();
UnwrappedIOValue::from(s).wrap().serialize(serializer)
let s = s.into_iter().map(to_value).collect::<Set<IOValue>>();
IOValue::new(s).serialize(serializer)
}
pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>

View File

@ -1,11 +1,8 @@
use crate::value::{IOValue, NestedValue};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct Symbol(pub String);
use crate::{IOValue, Symbol};
impl serde::Serialize for Symbol {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
IOValue::symbol(&self.0).serialize(serializer)
IOValue::symbol(self.inner().as_ref()).serialize(serializer)
}
}
@ -13,18 +10,18 @@ impl<'de> serde::Deserialize<'de> for Symbol {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
let v = IOValue::deserialize(deserializer)?;
let s = v.value().as_symbol().ok_or_else(|| serde::de::Error::custom("Expected symbol"))?;
Ok(Symbol(s.clone()))
Ok(Symbol::new(s.into_owned()))
}
}
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)
Symbol::new(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)
Symbol::deserialize(deserializer).map(|v| v.inner().to_owned())
}

View File

@ -0,0 +1,402 @@
use crate::{Value, IOValue, Map, ValueImpl, ExpectedKind};
use crate::serde::error::Error;
use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::iter::Iterator;
pub type Result<T> = std::result::Result<T, Error>;
pub struct Deserializer {
input: IOValue,
}
pub fn from_value<'de, T>(v: &IOValue) -> Result<T> where T: Deserialize<'de>
{
let mut de = Deserializer::from_value(v);
let t = T::deserialize(&mut de)?;
Ok(t)
}
impl Deserializer {
pub fn from_value(v: &IOValue) -> Self {
Deserializer { input: v.clone() }
}
}
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer
{
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
match self.input.value_class() {
crate::ValueClass::Atomic(a) => match a {
crate::AtomClass::Boolean => visitor.visit_bool(self.input.as_boolean().unwrap()),
crate::AtomClass::Float => visitor.visit_f32(self.input.as_float().unwrap()),
crate::AtomClass::Double => visitor.visit_f64(self.input.as_double().unwrap()),
crate::AtomClass::SignedInteger => {
let v = self.input.as_signed_integer().unwrap().into_owned();
match i64::try_from(&v) {
Ok(i) => visitor.visit_i64(i),
Err(_) => match u64::try_from(&v) {
Ok(u) => visitor.visit_u64(u),
Err(_) => Err(crate::Error::NumberOutOfRange((&v).into()))?,
}
}
}
crate::AtomClass::String => visitor.visit_str(self.input.as_string().unwrap().as_ref()),
crate::AtomClass::ByteString => self.deserialize_bytes(visitor),
crate::AtomClass::Symbol => Err(Error::CannotDeserializeAny),
}
crate::ValueClass::Compound(c) => match c {
crate::CompoundClass::Record => match self.input.label().as_symbol().map(|l| l.as_ref()) {
Some("tuple") => if self.input.len() == 0 {
self.deserialize_unit(visitor)
} else {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
},
Some("UnicodeScalar") => self.deserialize_char(visitor),
Some("None") | Some("Some") => self.deserialize_option(visitor),
_ => Err(Error::CannotDeserializeAny),
}
crate::CompoundClass::Sequence => visitor.visit_seq(VecSeq::new(self, self.input.iter())),
crate::CompoundClass::Set => Err(Error::CannotDeserializeAny),
crate::CompoundClass::Dictionary => visitor.visit_map(DictMap::new(self, self.input.entries())),
}
crate::ValueClass::Embedded => Err(Error::CannotDeserializeAny),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_bool(self.input.to_boolean()?)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i8(self.input.to_i8()??)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i16(self.input.to_i16()??)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i32(self.input.to_i32()??)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_i64(self.input.to_i64()??)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u8(self.input.to_u8()??)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u16(self.input.to_u16()??)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u32(self.input.to_u32()??)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_u64(self.input.to_u64()??)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
match self.input.as_float() {
Some(f) => visitor.visit_f32(f),
None => visitor.visit_f32(self.input.to_double()? as f32),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
match self.input.as_double() {
Some(d) => visitor.visit_f64(d),
None => visitor.visit_f64(self.input.to_float()? as f64),
}
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_simple_record("UnicodeScalar", Some(1)) {
if let Some(Ok(c)) = self.input.index(0).as_u32() {
return visitor.visit_char(char::from_u32(c).ok_or(Error::InvalidUnicodeScalar(c))?)
}
}
Err(Error::ExpectedUnicodeScalar)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_borrowed_str(self.input.to_str()?.as_ref())
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
self.deserialize_str(visitor)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_borrowed_bytes(self.input.to_bytestring()?.as_ref())
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_byte_buf(self.input.to_bytestring()?.into_owned())
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_record() {
match self.input.label().as_symbol().map(|l| l.as_ref()) {
Some("None") => if let None = self.input.iter().next() {
return visitor.visit_none();
},
Some("Some") => if let Some(v) = self.input.iter().next() {
self.input = v.into();
return visitor.visit_some(self);
},
_ => (),
}
}
Err(Error::ExpectedOption)
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_simple_record("tuple", Some(0)) {
visitor.visit_unit()
} else {
Err(ExpectedKind::SimpleRecord("tuple".to_owned()))?
}
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_simple_record(name, Some(0)) {
visitor.visit_unit()
} else {
Err(ExpectedKind::SimpleRecord(name.to_owned()))?
}
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
match super::magic::transmit_input_value(name, || Ok(self.input.clone()))? {
Some(v) => visitor.visit_u64(v),
None => if self.input.is_simple_record(name, Some(1)) {
self.input = self.input.index(0).into();
visitor.visit_newtype_struct(self)
} else {
Err(ExpectedKind::SimpleRecord(name.to_owned()))?
}
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
if self.input.is_sequence() {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else if self.input.is_set() {
// Hack around serde's model: Deserialize *sets* as
// sequences, too, and reconstruct them as Rust Sets
// on the visitor side.
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else {
Err(ExpectedKind::Sequence)?
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_simple_record("tuple", Some(len)) {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else {
Err(ExpectedKind::SimpleRecord("tuple".to_owned()))?
}
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_simple_record(name, Some(len)) {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else {
Err(ExpectedKind::SimpleRecord(name.to_owned()))?
}
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
if self.input.is_dictionary() {
visitor.visit_map(DictMap::new(self, self.input.entries()))
} else {
Err(ExpectedKind::Dictionary)?
}
}
fn deserialize_struct<V>(self,
name: &'static str,
fields: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_simple_record(name, Some(fields.len())) {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else {
Err(ExpectedKind::SimpleRecord(name.to_owned()))?
}
}
fn deserialize_enum<V>(self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_enum(self)
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_str(&self.input.value().to_symbol()?)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
visitor.visit_none()
}
}
pub struct VecSeq<'a, I: Iterator<Item = Value<IOValue>>> {
iter: I,
de: &'a mut Deserializer,
}
impl<'de, 'a, I: Iterator<Item = Value<IOValue>>> VecSeq<'a, I> {
fn new(de: &'a mut Deserializer, iter: I) -> Self {
VecSeq { iter, de }
}
}
impl<'de, 'a, I: Iterator<Item = Value<IOValue>>> SeqAccess<'de> for VecSeq<'a, I> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) ->
Result<Option<T::Value>>
where
T: DeserializeSeed<'de>
{
match self.iter.next() {
None => Ok(None),
Some(v) => {
self.de.input = v.into();
Ok(Some(seed.deserialize(&mut *self.de)?))
}
}
}
}
pub struct DictMap<'a> {
pending: Option<IOValue>,
iter: Box<dyn Iterator<Item = (Value<IOValue>, Value<IOValue>)> + 'a>,
de: &'a mut Deserializer,
}
impl<'a> DictMap<'a> {
fn new(
de: &'a mut Deserializer,
iter: Box<dyn Iterator<Item = (Value<IOValue>, Value<IOValue>)> + 'a>,
) -> Self {
DictMap{ pending: None, iter, de }
}
}
impl<'a, 'de> MapAccess<'de> for DictMap<'a> {
type Error = Error;
fn next_key_seed<K>(
&mut self,
seed: K,
) -> Result<Option<K::Value>> where K: DeserializeSeed<'de> {
match self.iter.next() {
None => Ok(None),
Some((k, v)) => {
self.pending = Some(v.into());
self.de.input = k.into();
Ok(Some(seed.deserialize(&mut *self.de)?))
}
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> where V: DeserializeSeed<'de> {
let v = self.pending.unwrap();
self.pending = None;
self.de.input = v;
Ok(seed.deserialize(&mut *self.de)?)
}
}
impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{
let v = self.input;
self.input = v.label().into();
let variant = seed.deserialize(&mut *self)?;
self.input = v;
Ok((variant, self))
}
}
impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
if self.input.is_record() {
if let Some(v) = self.input.iter().next() {
self.input = v.into();
return seed.deserialize(&mut *self);
}
}
Err(ExpectedKind::Record)?
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
if self.input.is_record() {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else {
Err(ExpectedKind::Record)?
}
}
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
if self.input.is_record() {
visitor.visit_seq(VecSeq::new(self, self.input.iter()))
} else {
Err(ExpectedKind::Record)?
}
}
}

View File

@ -1,4 +1,4 @@
use preserves::IOValue;
use crate::IOValue;
pub static MAGIC: &str = "$____Preserves_Serde_Magic";
@ -14,14 +14,12 @@ impl<'de> serde::de::Visitor<'de> for IOValueVisitor {
}
}
#[inline(always)]
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) ->
Result<S::Ok, S::Error>
{
serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64))
}
#[inline(always)]
pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<IOValue, D::Error>
{
deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor)
@ -29,7 +27,6 @@ pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<
//---------------------------------------------------------------------------
#[inline]
pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> Option<IOValue> {
if name == MAGIC {
let b = unsafe { Box::from_raw(*((magic_value as *const T) as *const u64) as *mut IOValue) };
@ -40,7 +37,6 @@ pub fn receive_output_value<T: ?Sized>(name: &'static str, magic_value: &T) -> O
}
}
#[inline]
pub fn transmit_input_value<F>(name: &'static str, f: F) -> Result<Option<u64>, crate::error::Error>
where F: FnOnce() -> Result<IOValue, crate::error::Error>
{
@ -55,7 +51,6 @@ where F: FnOnce() -> Result<IOValue, crate::error::Error>
//---------------------------------------------------------------------------
// This part is a terrible hack
impl serde::Serialize for IOValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
super::magic::output_value(serializer, self.clone())
@ -67,4 +62,3 @@ impl<'de> serde::Deserialize<'de> for IOValue {
super::magic::input_value(deserializer)
}
}

View File

@ -0,0 +1,8 @@
pub mod de;
pub mod magic;
pub mod ser;
pub use de::Deserializer;
pub use de::from_value;
pub use ser::Serializer;
pub use ser::to_value;

View File

@ -1,4 +1,4 @@
use crate::value::{Value, repr::Record, Map, IOValue};
use crate::{Value, Record, Bytes, Symbol, Map, IOValue};
use serde::Serialize;
#[derive(Debug)]
@ -25,7 +25,7 @@ pub struct SerializeDictionary {
}
pub struct SerializeRecord {
r: Record<IOValue>,
label_and_fields: Vec<Value<IOValue>>,
}
pub struct SerializeSequence {
@ -44,75 +44,75 @@ impl serde::Serializer for Serializer {
type SerializeStructVariant = SerializeRecord;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_char(self, v: char) -> Result<Self::Ok> {
Ok(Value::simple_record1("UnicodeScalar", Value::from(v as u32).wrap()).wrap())
Ok(IOValue::record(IOValue::symbol("UnicodeScalar"), vec![IOValue::new(v as u32)]))
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(v))
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
Ok(Value::from(v).wrap())
Ok(IOValue::new(Bytes(v)))
}
fn serialize_none(self) -> Result<Self::Ok> {
Ok(Value::simple_record0("None").wrap())
OK(IOValue::record(IOValue::symbol("None"), vec![]))
}
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
Ok(Value::simple_record1("Some", to_value(v)).wrap())
Ok(IOValue::record(IOValue::symbol("Some"), vec![to_value(v).into()]))
}
fn serialize_unit(self) -> Result<Self::Ok> {
Ok(Value::simple_record0("tuple").wrap())
Ok(IOValue::record(IOValue::symbol("tuple"), vec![]))
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
Ok(Value::simple_record0(name).wrap())
Ok(IOValue::record(IOValue::symbol(name), vec![]))
}
fn serialize_unit_variant(self,
@ -121,7 +121,7 @@ impl serde::Serializer for Serializer {
variant_name: &'static str) ->
Result<Self::Ok>
{
Ok(Value::simple_record0(variant_name).wrap())
Ok(IOValue::record(IOValue::symbol(variant_name), vec![]))
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
@ -131,7 +131,7 @@ impl serde::Serializer for Serializer {
Some(v) => Ok(v),
None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
Ok(Value::simple_record1(name, to_value(value)).wrap())
Ok(IOValue::record(IOValue::symbol(name), vec![to_value(value).into()]))
}
}
}
@ -143,7 +143,7 @@ impl serde::Serializer for Serializer {
value: &T) ->
Result<Self::Ok> where T: Serialize
{
Ok(Value::simple_record1(variant_name, to_value(value)).wrap())
Ok(IOValue::record(IOValue::symbol(variant_name), vec![to_value(value).into()]))
}
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
@ -152,13 +152,13 @@ impl serde::Serializer for Serializer {
}
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
Ok(SerializeRecord { r: Value::simple_record("tuple", count) })
Ok(SerializeRecord::new("tuple"))
}
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
Result<Self::SerializeTupleStruct>
{
Ok(SerializeRecord { r: Value::simple_record(name, count) })
Ok(SerializeRecord::new(name))
}
fn serialize_tuple_variant(self,
@ -168,7 +168,7 @@ impl serde::Serializer for Serializer {
count: usize) ->
Result<Self::SerializeTupleVariant>
{
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) })
Ok(SerializeRecord::new(variant_name))
}
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
@ -176,7 +176,7 @@ impl serde::Serializer for Serializer {
}
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
Ok(SerializeRecord { r: Value::simple_record(name, count) })
Ok(SerializeRecord::new(name))
}
fn serialize_struct_variant(self,
@ -186,7 +186,7 @@ impl serde::Serializer for Serializer {
count: usize) ->
Result<Self::SerializeStructVariant>
{
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) })
Ok(SerializeRecord::new(variant_name))
}
}
@ -206,19 +206,23 @@ impl serde::ser::SerializeMap for SerializeDictionary {
}
fn end(self) -> Result<Self::Ok> {
Ok(Value::from(self.items).wrap())
Ok(IOValue::new(self.items))
}
}
impl SerializeRecord {
fn new(label: &str) -> Self {
SerializeRecord { label_and_fields: vec![Value::new(Symbol::new(label))] }
}
fn push<T: ?Sized>(&mut self, value: &T)
where T: Serialize
{
self.r.fields_vec_mut().push(to_value(value))
self.label_and_fields.push(to_value(value).into())
}
fn finish(self) -> IOValue {
self.r.finish().wrap()
IOValue::new(Record::_from_vec(self.label_and_fields))
}
}
@ -306,7 +310,7 @@ impl serde::ser::SerializeSeq for SerializeSequence {
}
fn end(self) -> Result<Self::Ok> {
Ok(Value::from(self.vec).wrap())
Ok(IOValue::new(self.vec))
}
}