Merge preserves-serde into a feature of preserves
This commit is contained in:
parent
e1d86bd1ec
commit
d01e247d04
|
@ -3,7 +3,6 @@ members = [
|
|||
"preserves",
|
||||
"preserves-path",
|
||||
"preserves-schema",
|
||||
"preserves-serde",
|
||||
"preserves-tools",
|
||||
]
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
testdata.bin
|
Binary file not shown.
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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()))
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"]
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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>;
|
||||
|
|
@ -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 {
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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()?;
|
|
@ -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>
|
|
@ -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())
|
||||
}
|
|
@ -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)?
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue