mod pp;
use crate::{Error, ErrorType};
pub use pp::*;
use serde_ext::ser;
use std::io::Write;
use std::str;
use value_trait::generator::BaseGenerator;
macro_rules! iomap {
($e:expr) => {
($e).map_err(|err| Error::generic(ErrorType::Io(err)))
};
}
#[cfg_attr(not(feature = "no-inline"), inline)]
pub fn to_vec<T>(to: &T) -> crate::Result<Vec<u8>>
where
T: ser::Serialize + ?Sized,
{
let v = Vec::with_capacity(512);
let mut s = Serializer(v);
to.serialize(&mut s).map(|()| s.0)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
pub fn to_string<T>(to: &T) -> crate::Result<String>
where
T: ser::Serialize + ?Sized,
{
to_vec(to).map(|v| unsafe { String::from_utf8_unchecked(v) })
}
#[cfg_attr(not(feature = "no-inline"), inline)]
pub fn to_writer<T, W>(writer: W, to: &T) -> crate::Result<()>
where
T: ser::Serialize + ?Sized,
W: Write,
{
let mut s = Serializer(writer);
to.serialize(&mut s)
}
struct Serializer<W: Write>(W);
impl<W> BaseGenerator for Serializer<W>
where
W: Write,
{
type T = W;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn get_writer(&mut self) -> &mut Self::T {
&mut self.0
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn write_min(&mut self, _slice: &[u8], min: u8) -> std::io::Result<()> {
self.0.write_all(&[min])
}
}
struct SerializeSeq<'serializer, W: Write + 'serializer> {
s: &'serializer mut Serializer<W>,
first: bool,
}
impl<'serializer, W> ser::SerializeSeq for SerializeSeq<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeSeq {
ref mut s,
ref mut first,
..
} = *self;
if *first {
*first = false;
value.serialize(&mut **s)
} else {
iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.first {
Ok(())
} else {
iomap!(self.s.write(b"]"))
}
}
}
impl<'serializer, W> ser::SerializeTuple for SerializeSeq<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeSeq {
ref mut s,
ref mut first,
} = *self;
if *first {
*first = false;
value.serialize(&mut **s)
} else {
iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.first {
Ok(())
} else {
iomap!(self.s.write(b"]"))
}
}
}
impl<'serializer, W> ser::SerializeTupleStruct for SerializeSeq<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeSeq {
ref mut s,
ref mut first,
} = *self;
if *first {
*first = false;
value.serialize(&mut **s)
} else {
iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.first {
Ok(())
} else {
iomap!(self.s.write(b"]"))
}
}
}
impl<'serializer, W> ser::SerializeTupleVariant for SerializeSeq<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeSeq {
ref mut s,
ref mut first,
} = *self;
if *first {
*first = false;
value.serialize(&mut **s)
} else {
iomap!(s.write(b",")).and_then(|()| value.serialize(&mut **s))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.first {
Ok(())
} else {
iomap!(self.s.write(b"]}"))
}
}
}
struct SerializeMap<'serializer, W: Write + 'serializer> {
s: &'serializer mut Serializer<W>,
first: bool,
wrote_closing: bool,
}
impl<'serializer, W> ser::SerializeMap for SerializeMap<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeMap {
ref mut s,
ref mut first,
..
} = *self;
if *first {
*first = false;
key.serialize(MapKeySerializer { s: &mut **s })
.and_then(|()| iomap!(s.write(b":")))
} else {
iomap!(s.write(b","))
.and_then(|()| key.serialize(MapKeySerializer { s: &mut **s }))
.and_then(|()| iomap!(s.write(b":")))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeMap { ref mut s, .. } = *self;
value.serialize(&mut **s)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.wrote_closing {
Ok(())
} else {
iomap!(self.s.write(b"}"))
}
}
}
fn key_must_be_a_string() -> Error {
Error::generic(ErrorType::KeyMustBeAString)
}
struct MapKeySerializer<'serializer, W: Write + 'serializer> {
s: &'serializer mut Serializer<W>,
}
impl<'serializer, W> ser::Serializer for MapKeySerializer<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_str(self, value: &str) -> Result<(), Self::Error> {
self.s.serialize_str(value)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<(), Self::Error> {
self.s.serialize_str(variant)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
value.serialize(self)
}
type SerializeSeq = ser::Impossible<(), Error>;
type SerializeTuple = ser::Impossible<(), Error>;
type SerializeTupleStruct = ser::Impossible<(), Error>;
type SerializeTupleVariant = ser::Impossible<(), Error>;
type SerializeMap = ser::Impossible<(), Error>;
type SerializeStruct = ser::Impossible<(), Error>;
type SerializeStructVariant = ser::Impossible<(), Error>;
fn serialize_bool(self, _value: bool) -> Result<(), Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
iomap!(self
.s
.write_char(b'"')
.and_then(|()| self.s.write_int(v))
.and_then(|()| self.s.write_char(b'"')))
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
self.s.serialize_str(&v.to_string())
}
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
Err(key_must_be_a_string())
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
Err(key_must_be_a_string())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Err(key_must_be_a_string())
}
}
impl<'serializer, W> ser::SerializeStruct for SerializeMap<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeMap {
ref mut s,
ref mut first,
..
} = *self;
if *first {
*first = false;
iomap!(s.write_simple_string(key).and_then(|()| s.write(b":")))
.and_then(|()| value.serialize(&mut **s))
} else {
iomap!(s
.write(b",")
.and_then(|()| s.write_simple_string(key))
.and_then(|()| s.write(b":")))
.and_then(|()| value.serialize(&mut **s))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.first {
Ok(())
} else {
iomap!(self.s.write(b"}"))
}
}
}
struct SerializeStructVariant<'serializer, W: Write + 'serializer> {
s: &'serializer mut Serializer<W>,
first: bool,
}
impl<'serializer, W> ser::SerializeStructVariant for SerializeStructVariant<'serializer, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
let SerializeStructVariant {
ref mut s,
ref mut first,
..
} = *self;
if *first {
*first = false;
iomap!(s.write_simple_string(key).and_then(|()| s.write(b":")))
.and_then(|()| value.serialize(&mut **s))
} else {
iomap!(s
.write(b",")
.and_then(|()| s.write_simple_string(key))
.and_then(|()| s.write(b":")))
.and_then(|()| value.serialize(&mut **s))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn end(self) -> Result<Self::Ok, Self::Error> {
iomap!(self.s.write(b"}")).and_then(move |()| {
if self.first {
Ok(())
} else {
iomap!(self.s.write(b"}"))
}
})
}
}
impl<'writer, W> ser::Serializer for &'writer mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
type SerializeSeq = SerializeSeq<'writer, W>;
type SerializeTuple = SerializeSeq<'writer, W>;
type SerializeTupleStruct = SerializeSeq<'writer, W>;
type SerializeTupleVariant = SerializeSeq<'writer, W>;
type SerializeMap = SerializeMap<'writer, W>;
type SerializeStruct = SerializeMap<'writer, W>;
type SerializeStructVariant = SerializeStructVariant<'writer, W>;
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
if v {
iomap!(self.write(b"true"))
} else {
iomap!(self.write(b"false"))
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_int(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_float(f64::from(v)))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_float(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
let mut buf = [0; 4];
iomap!(self.write_simple_string(v.encode_utf8(&mut buf)))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_string(v))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
iomap!(self.write(b"[").and_then(|()| {
if let Some((first, rest)) = v.split_first() {
self.write_int(*first).and_then(|()| {
for v in rest {
self.write(b",").and_then(|()| self.write_int(*v))?;
}
self.write(b"]")
})
} else {
self.write(b"]")
}
}))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
self.serialize_unit()
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
value.serialize(self)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
iomap!(self.write(b"null"))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
self.serialize_unit()
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
iomap!(self.write_simple_string(variant))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
value.serialize(self)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + serde_ext::Serialize,
{
iomap!(self
.write(b"{")
.and_then(|()| self.write_simple_string(variant))
.and_then(|()| self.write(b":")))
.and_then(|()| value.serialize(&mut *self))
.and_then(|()| iomap!(self.write(b"}")))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
if len == Some(0) {
iomap!(self.write(b"[]"))
} else {
iomap!(self.write(b"["))
}
.map(move |()| SerializeSeq {
s: self,
first: true,
})
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.serialize_seq(Some(len))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.serialize_seq(Some(len))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
iomap!(self
.write(b"{")
.and_then(|()| self.write_simple_string(variant))
.and_then(|()| self.write(b":")))?;
self.serialize_seq(Some(len))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
let mut wrote_closing = false;
if len == Some(0) {
wrote_closing = true;
iomap!(self.write(b"{}"))
} else {
iomap!(self.write(b"{"))
}
.map(move |()| SerializeMap {
s: self,
first: true,
wrote_closing,
})
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
self.serialize_map(Some(len))
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
iomap!(self
.write(b"{")
.and_then(|()| self.write_simple_string(variant))
.and_then(|()| self.write(b":")))
.and_then(move |()| {
if len == 0 {
iomap!(self.write(b"{}"))
} else {
iomap!(self.write(b"{"))
}
.map(move |()| SerializeStructVariant {
s: self,
first: true,
})
})
}
}
#[cfg(test)]
mod test {
#![allow(clippy::ignored_unit_patterns)]
#[cfg(not(target_arch = "wasm32"))]
use crate::{OwnedValue as Value, StaticNode};
#[cfg(not(target_arch = "wasm32"))]
use proptest::prelude::*;
#[test]
fn enum_tuple() {
#[derive(serde::Serialize, Clone)]
enum ErrType {
Instruction(i64, i64),
}
let err = ErrType::Instruction(2, 68800);
assert_eq!(
crate::to_string(&err).expect("failed to serialize"),
"{\"Instruction\":[2,68800]}",
);
}
#[test]
fn print_serde() {
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
enum Segment {
Id { mid: usize },
}
assert_eq!(
"{\"Id\":{\"mid\":0}}",
crate::to_string(&Segment::Id { mid: 0 }).expect("to_string")
);
}
#[test]
fn numerical_map_serde() {
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
struct Foo {
pub bar: HashMap<i32, i32>,
}
let mut foo = Foo {
bar: HashMap::new(),
};
foo.bar.insert(1337, 1337);
assert_eq!(
r#"{"bar":{"1337":1337}}"#,
crate::to_string(&foo).expect("to_string")
);
}
#[cfg(not(feature = "128bit"))]
#[cfg(not(target_arch = "wasm32"))]
fn arb_json_value() -> BoxedStrategy<Value> {
let leaf = prop_oneof![
Just(Value::Static(StaticNode::Null)),
any::<bool>().prop_map(Value::from),
any::<i8>().prop_map(Value::from),
any::<i16>().prop_map(Value::from),
any::<i32>().prop_map(Value::from),
any::<i64>().prop_map(Value::from),
any::<u8>().prop_map(Value::from),
any::<u16>().prop_map(Value::from),
any::<u32>().prop_map(Value::from),
any::<u64>().prop_map(Value::from),
".*".prop_map(Value::from),
];
leaf.prop_recursive(
8, 256, 10, |inner| {
prop_oneof![
prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
]
},
)
.boxed()
}
#[cfg(feature = "128bit")]
#[cfg(not(target_arch = "wasm32"))]
fn arb_json_value() -> BoxedStrategy<Value> {
let leaf = prop_oneof![
Just(Value::Static(StaticNode::Null)),
any::<bool>().prop_map(Value::from),
any::<i8>().prop_map(Value::from),
any::<i16>().prop_map(Value::from),
any::<i32>().prop_map(Value::from),
any::<i64>().prop_map(Value::from),
any::<i128>().prop_map(Value::from),
any::<u8>().prop_map(Value::from),
any::<u16>().prop_map(Value::from),
any::<u32>().prop_map(Value::from),
any::<u64>().prop_map(Value::from),
any::<u128>().prop_map(Value::from),
".*".prop_map(Value::from),
];
leaf.prop_recursive(
8, 256, 10, |inner| {
prop_oneof![
prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
prop::collection::hash_map(".*", inner, 0..10).prop_map(Value::from),
]
},
)
.boxed()
}
#[cfg(not(target_arch = "wasm32"))]
proptest! {
#![proptest_config(ProptestConfig {
.. ProptestConfig::default()
})]
#[test]
fn prop_json_encode_decode(val in arb_json_value()) {
let mut encoded = crate::to_vec(&val).expect("to_vec");
println!("{}", String::from_utf8_lossy(&encoded.clone()));
let res: Value = crate::from_slice(encoded.as_mut_slice()).expect("can't convert");
assert_eq!(val, res);
}
}
}