Skip to content

Commit f8c939a

Browse files
committed
feat: use serialize to provide Writable trait for ordered types
1 parent 66bdf3d commit f8c939a

File tree

17 files changed

+2627
-195
lines changed

17 files changed

+2627
-195
lines changed

src/serde/value/borrowed/ordered/se.rs

Lines changed: 798 additions & 0 deletions
Large diffs are not rendered by default.

src/serde/value/owned/ordered/se.rs

Lines changed: 749 additions & 0 deletions
Large diffs are not rendered by default.

src/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod impls;
77

88
#[cfg(not(target_arch = "wasm32"))]
99
use crate::to_borrowed_value;
10-
use crate::{Deserializer, owned::Value, tape::Node, to_owned_value};
10+
use crate::{cow::Cow, Deserializer, owned::Value, tape::Node, to_owned_value};
1111
#[cfg(not(target_arch = "wasm32"))]
1212
use proptest::prelude::*;
1313
use value_trait::prelude::*;
@@ -253,10 +253,10 @@ proptest! {
253253
{ // we can't do 128 bit w/ serde
254254
use crate::{deserialize, BorrowedValue, OwnedValue};
255255
let mut e = encoded.clone();
256-
let res: OwnedValue = deserialize(&mut e).expect("can't convert");
256+
let res: OwnedValue = deserialize::<OwnedValue, String>(&mut e).expect("can't convert");
257257
assert_eq!(val, res);
258258
let mut e = encoded;
259-
let res: BorrowedValue = deserialize(&mut e).expect("can't convert");
259+
let res: BorrowedValue = deserialize::<BorrowedValue, Cow<'_, str>>(&mut e).expect("can't convert");
260260
assert_eq!(val, res);
261261
}
262262
}

src/tests/serde.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ proptest! {
10081008
let v_simd_owned = to_owned_value(d2).expect("to_owned_value failed");
10091009
let v_simd_borrowed = to_borrowed_value(d3).expect("to_borrowed_value failed");
10101010
assert_eq!(v_simd_borrowed, v_simd_owned);
1011-
let v_deserialize: OwnedValue = deserialize(d4).expect("deserialize failed");
1011+
let v_deserialize: OwnedValue = deserialize::<OwnedValue, String>(d4).expect("deserialize failed");
10121012
assert_eq!(v_deserialize, v_simd_owned);
10131013
}
10141014

src/value.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub use self::borrowed::{
6363
Value as BorrowedValue, to_value as to_borrowed_value,
6464
to_value_with_buffers as to_borrowed_value_with_buffers,
6565
};
66-
#[cfg(feature = "preserve_ordered")]
66+
#[cfg(feature = "preserve_order")]
6767
pub use self::borrowed::ordered::{
6868
Value as OrderedBorrowedValue, to_value as to_ordered_borrowed_value,
6969
to_value_with_buffers as to_ordered_borrowed_value_with_buffers,
@@ -72,7 +72,7 @@ pub use self::owned::{
7272
Value as OwnedValue, to_value as to_owned_value,
7373
to_value_with_buffers as to_owned_value_with_buffers,
7474
};
75-
#[cfg(feature = "preserve_ordered")]
75+
#[cfg(feature = "preserve_order")]
7676
pub use self::owned::ordered::{
7777
Value as OrderedOwnedValue, to_value as to_ordered_owned_value,
7878
to_value_with_buffers as to_ordered_owned_value_with_buffers,

src/value/borrowed.rs

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,11 @@ impl<'de> BorrowDeserializer<'de> {
428428
// element so we eat this
429429
for _ in 0..len {
430430
if let Node::String(key) = unsafe { self.0.next_() } {
431-
#[cfg(all(not(feature = "value-no-dup-keys"), not(feature = "preserve_order")))]
431+
#[cfg(not(feature = "value-no-dup-keys"))]
432432
unsafe {
433433
res.insert_nocheck(key.into(), self.parse());
434434
};
435-
#[cfg(any(feature = "value-no-dup-keys", feature = "preserve_order"))]
435+
#[cfg(feature = "value-no-dup-keys")]
436436
res.insert(key.into(), self.parse());
437437
} else {
438438
unreachable!("parse_map: key not a string");
@@ -490,11 +490,11 @@ impl<'tape, 'de> BorrowSliceDeserializer<'tape, 'de> {
490490
// element so we eat this
491491
for _ in 0..len {
492492
if let Node::String(key) = unsafe { self.next_() } {
493-
#[cfg(all(not(feature = "value-no-dup-keys"), not(feature = "preserve_order")))]
493+
#[cfg(not(feature = "value-no-dup-keys"))]
494494
unsafe {
495495
res.insert_nocheck(key.into(), self.parse());
496496
};
497-
#[cfg(any(feature = "value-no-dup-keys", feature = "preserve_order"))]
497+
#[cfg(feature = "value-no-dup-keys")]
498498
res.insert(key.into(), self.parse());
499499
} else {
500500
unreachable!("parse_map: key needs to be a string");
@@ -1136,59 +1136,6 @@ mod test {
11361136
assert_eq!(result_keys, expected_keys);
11371137
}
11381138

1139-
#[cfg(feature = "preserve_order")]
1140-
#[test]
1141-
fn preserve_order_33_keys() {
1142-
// halfbrown uses Vec for <=32 keys, switches to HashMap at 33+
1143-
// This is where order gets lost without IndexMap
1144-
let keys: Vec<String> = (0..33).map(|i| format!("key_{}", i)).collect();
1145-
let json_pairs: Vec<String> = keys.iter().map(|k| format!(r#""{}": {}"#, k, 1)).collect();
1146-
let json = format!("{{{}}}", json_pairs.join(", "));
1147-
let mut input = json.into_bytes();
1148-
1149-
let v = to_value(input.as_mut_slice()).expect("valid JSON");
1150-
let obj = v.as_object().expect("is object");
1151-
let result_keys: Vec<&str> = obj.keys().map(|k| k.as_ref()).collect();
1152-
let expected_keys: Vec<&str> = keys.iter().map(|s| s.as_str()).collect();
1153-
1154-
assert_eq!(result_keys, expected_keys);
1155-
}
1156-
1157-
#[cfg(feature = "preserve_order")]
1158-
#[test]
1159-
fn preserve_order_50_keys() {
1160-
// Test well past the threshold
1161-
let keys: Vec<String> = (0..50).map(|i| format!("key_{}", i)).collect();
1162-
let json_pairs: Vec<String> = keys.iter().map(|k| format!(r#""{}": {}"#, k, 1)).collect();
1163-
let json = format!("{{{}}}", json_pairs.join(", "));
1164-
let mut input = json.into_bytes();
1165-
1166-
let v = to_value(input.as_mut_slice()).expect("valid JSON");
1167-
let obj = v.as_object().expect("is object");
1168-
let result_keys: Vec<&str> = obj.keys().map(|k| k.as_ref()).collect();
1169-
let expected_keys: Vec<&str> = keys.iter().map(|s| s.as_str()).collect();
1170-
1171-
assert_eq!(result_keys, expected_keys);
1172-
}
1173-
1174-
#[cfg(feature = "preserve_order")]
1175-
#[test]
1176-
fn preserve_order_roundtrip_33_keys() {
1177-
let keys: Vec<String> = (0..33).map(|i| format!("key_{}", i)).collect();
1178-
let json_pairs: Vec<String> = keys.iter().map(|k| format!(r#""{}": {}"#, k, 1)).collect();
1179-
let json = format!("{{{}}}", json_pairs.join(", "));
1180-
let mut input = json.into_bytes();
1181-
1182-
let v = to_value(input.as_mut_slice()).expect("valid JSON");
1183-
let mut serialized = v.encode();
1184-
let v2 = to_value(unsafe { serialized.as_bytes_mut() }).expect("valid JSON");
1185-
1186-
let keys1: Vec<&str> = v.as_object().unwrap().keys().map(|k| k.as_ref()).collect();
1187-
let keys2: Vec<&str> = v2.as_object().unwrap().keys().map(|k| k.as_ref()).collect();
1188-
1189-
assert_eq!(keys1, keys2);
1190-
}
1191-
11921139
// #[test]
11931140
// fn size() {
11941141
// assert_eq!(std::mem::size_of::<Value>(), 24);

src/value/borrowed/from.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,12 @@ impl<'value> From<Object<'value>> for Value<'value> {
219219
}
220220

221221
#[cfg(feature = "preserve_order")]
222-
impl<'value> From<indexmap::IndexMap<Cow<'value, str>, Value<'value>>> for Value<'value> {
223-
fn from(v: indexmap::IndexMap<Cow<'value, str>, Value<'value>>) -> Self {
224-
Self::Object(Box::new(v.into_iter().collect()))
222+
impl<'value, K, S> From<indexmap::IndexMap<K, Value<'value>, S>> for Value<'value>
223+
where
224+
K: Into<Cow<'value, str>>,
225+
S: std::hash::BuildHasher,
226+
{
227+
fn from(v: indexmap::IndexMap<K, Value<'value>, S>) -> Self {
228+
Self::Object(Box::new(v.into_iter().map(|(k, v)| (k.into(), v)).collect()))
225229
}
226230
}

src/value/borrowed/ordered.rs

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,22 @@
2020
/// a["key"] = "value".into();
2121
/// assert_eq!(a["key"], "value");
2222
/// ```
23+
/// Partial equality comparison impls
24+
pub mod cmp;
25+
/// From converter impls
2326
pub mod from;
27+
/// Provide Writable trait
28+
pub mod serialize;
2429

2530
use crate::{Buffers, prelude::*};
26-
use crate::{Deserializer, Node, Result};
31+
use crate::{Deserializer, Node, ObjectHasher, Result};
2732
use crate::cow::Cow;
2833
use indexmap::IndexMap;
2934
use std::fmt;
3035
use std::ops::{Index, IndexMut};
3136

3237
/// Representation of a JSON object
33-
pub type Object<'value> = IndexMap<Cow<'value, str>, Value<'value>, std::hash::RandomState>;
38+
pub type Object<'value> = IndexMap<Cow<'value, str>, Value<'value>, ObjectHasher>;
3439

3540
/// Representation of a JSON array
3641
pub type Array<'value> = Vec<Value<'value>>;
@@ -74,7 +79,7 @@ pub fn to_value_with_buffers<'value>(
7479

7580
/// Borrowed JSON-DOM Value, consider using the `ValueTrait`
7681
/// to access its content
77-
#[derive(Debug, Clone, PartialEq)]
82+
#[derive(Debug, Clone)]
7883
#[cfg_attr(feature = "ordered-float", derive(Eq))]
7984
pub enum Value<'value> {
8085
/// Static values
@@ -175,7 +180,7 @@ impl<'value> ValueBuilder<'value> for Value<'value> {
175180
fn object_with_capacity(capacity: usize) -> Self {
176181
Self::Object(Box::new(Object::with_capacity_and_hasher(
177182
capacity,
178-
std::hash::RandomState::default(),
183+
ObjectHasher::default(),
179184
)))
180185
}
181186
}
@@ -421,7 +426,7 @@ impl<'de> BorrowDeserializer<'de> {
421426

422427
#[cfg_attr(not(feature = "no-inline"), inline)]
423428
fn parse_map(&mut self, len: usize) -> Value<'de> {
424-
let mut res = Object::with_capacity_and_hasher(len, std::hash::RandomState::default());
429+
let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());
425430

426431
// Since we checked if it's empty we know that we at least have one
427432
// element so we eat this
@@ -931,43 +936,6 @@ mod test {
931936
assert_eq!(Value::default(), Value::null());
932937
}
933938

934-
#[cfg(not(target_arch = "wasm32"))]
935-
use proptest::prelude::*;
936-
937-
#[cfg(not(target_arch = "wasm32"))]
938-
fn arb_value() -> BoxedStrategy<Value<'static>> {
939-
let leaf = prop_oneof![
940-
Just(Value::Static(StaticNode::Null)),
941-
any::<bool>()
942-
.prop_map(StaticNode::Bool)
943-
.prop_map(Value::Static),
944-
any::<i64>()
945-
.prop_map(StaticNode::I64)
946-
.prop_map(Value::Static),
947-
any::<u64>()
948-
.prop_map(StaticNode::U64)
949-
.prop_map(Value::Static),
950-
any::<f64>()
951-
.prop_map(StaticNode::from)
952-
.prop_map(Value::Static),
953-
".*".prop_map(Value::from),
954-
];
955-
leaf.prop_recursive(
956-
8, // 8 levels deep
957-
256, // Shoot for maximum size of 256 nodes
958-
10, // We put up to 10 items per collection
959-
|inner| {
960-
prop_oneof![
961-
// Take the inner strategy and make the two recursive cases.
962-
prop::collection::vec(inner.clone(), 0..10).prop_map(Value::from),
963-
prop::collection::hash_map(".*".prop_map(Cow::from), inner, 0..10)
964-
.prop_map(|m| m.into_iter().collect()),
965-
]
966-
},
967-
)
968-
.boxed()
969-
}
970-
971939
#[test]
972940
fn preserve_order_33_keys() {
973941
// halfbrown uses Vec for <=32 keys, switches to HashMap at 33+

0 commit comments

Comments
 (0)